12

サーバーのような方法で外部スクリプトを開いたままにするために、Python でサブプロセスを使用しようとしています。外部スクリプトは、最初にモデルを読み込みます。これが完了すると、STDIN 経由で要求を受け入れ、処理された文字列を STDOUT に返します。

これまでのところ、私は試しました

tokenizer = subprocess.Popen([tokenizer_path, '-l', lang_prefix], stdin=subprocess.PIPE, stdout=subprocess.PIPE)

ただし使えない

tokenizer.stdin.write(input_string+'\n')
out = self._tokenizer.stdout.readline()

stdout.read()サブプロセスを使用して input_strings を繰り返し処理するために、 orを使用しても、 out は空になりますstdout.readline()。ただし、STDOUTを読み取る前に標準入力を閉じると機能しtokenizer.stdin.close()ますが、これはサブプロセスを閉じます。これは、別のリクエストを送信する前に外部スクリプト全体を再度リロードする必要があるため、必要なものではありません。

サブプロセスを閉じて再度開くことなく、Pythonでサーバーのような方法で使用する方法はありますか?

4

2 に答える 2

6

この Answerのおかげで、サブプロセスと適切に通信するには、スレーブ ハンドルを使用する必要があることがわかりました。

master, slave = pty.openpty()
tokenizer = subprocess.Popen(script, shell=True stdin=subprocess.PIPE, stdout=slave)
stdin_handle = process.stdin
stdout_handle = os.fdopen(master)

これで、サブプロセスを閉じずにサブプロセスと通信できます

stdin_handle.write(input)
stdout_handle.readline() #gets the processed input
于 2012-11-28T13:09:37.463 に答える
2

外部スクリプトはおそらくその出力をバッファリングするので、子のバッファがフラッシュされたときにのみ、父でそれを読み取ることができます(子はそれを自分で行う必要があります)。バッファをフラッシュする1つの方法は、おそらく入力を閉じることです。これは、適切な方法で終了し、プロセスでバッファをフラッシュするためです。

外部プログラムを制御できる場合(つまり、パッチを適用できる場合)、出力が生成された後にフラッシュを挿入します。

そうしないと、プログラムを疑似TTYに接続することで、出力をバッファリングしないようにすることができます(stdlibを含む多くのプログラムは、出力がTTYに送信されるときに、バッファリングは必要ないと想定しています)。しかし、これは少し注意が必要です。

于 2012-11-28T12:54:32.487 に答える