4

私はしばらくの間この問題に悩まされていて、解決策を見つけることができないようです.subprocess.Popen()を使用して、私のためにいくつかの重い計算を行うC ++アプリにアクセスしていますが、 Popen().stdout.read(); でフリーズし続けます。これがpythonコードです:

process = subprocess.Popen(['/path/to/my/executable'], shell=False, 
stdout=subprocess.PIPE, stdin=subprocess.PIPE)
process.stdin.write("Some String")
print process.stdout.read()#It freezes here

ここにC++コードがあります:

int main(int argc, char** argv) {
    ...Prep work...
    while (1) {
        string input;
        cin>>input;
    ...Some Work ...
        cout<< response;
    }
}

C++ コードは shell で完全に動作しますが、Python でフリーズする理由がわかりません

4

2 に答える 2

3

communicate()代わりに使用してください:

import subprocess
process = subprocess.Popen(['app'], shell=False,
                           stdout=subprocess.PIPE,
                           stdin=subprocess.PIPE)
out, err = process.communicate("Some String")
print out

また、ある時点で C++ プロセスを終了してください。たとえば、入力ストリームの最後に到達した場合:

#include <string>
#include <iostream>
using namespace std;

int main(int argc, char** argv) {
    //...Prep work...
    while (cin) {  // <-- Will eventually reach the end of the input stream
        string input;
        cin >> input;
        //...Some Work ...
        string response = input;
        cout << response;
    }
}

Python のドキュメントには、これに関する警告があります: http://docs.python.org/2/library/subprocess.html#subprocess.Popen.stdin (右上)

外部アプリに書き込むと、データがキューに入れられる可能性があることが説明されています。また、外部アプリの出力もキューに入れられる可能性があります。communicate() は、外部アプリに送信しているコンテンツを「フラッシュ」し、アプリが終了するまで待ちます。

を使用communicate()すると、外部アプリの出力全体がメモリに取得されます。実用的でない場合 (たとえば、大量の出力)、stdin および stdout オブジェクトを使用して書き込みまたは読み取りを行うことができます。「デッドロック」しないように注意する必要があります。

import subprocess

process = subprocess.Popen(['app'], shell=False,
                           stdout=subprocess.PIPE,
                           stdin=subprocess.PIPE)
process.stdin.write("Some String")
process.stdin.close()  # <-- Makes sure the external app gets an EOF while
                       #     reading its input stream.
for line in process.stdout.readlines():
    print line

ただし、この手法を使用しても、書き込み中にブロックされないように、外部アプリに与える入力が十分に小さいことを確認してください。

入力も非常に大きい場合は、読み取りと書き込みがブロックされていないことを確認する必要があります。その場合、スレッドの使用はおそらく良い選択です。

于 2013-06-19T19:11:45.033 に答える
0

通常、非ブロッキング IO が必要です。1) データがなくなるまですべての応答を読み取り、2) サブプロセスに何かを発行し、1-2 を繰り返します。スレッドの使用も役立ちます。

于 2015-05-30T20:38:26.853 に答える