4

Pythonでプロセスを生成し、双方向の通信ができるようにしたいと思います。もちろん、Pexpectはこれを行い、実際に私が行くかもしれない方法です。ただし、それは完全に理想的ではありません。

私の理想的な状況は、標準のPythonライブラリのみを含むクロスプラットフォームの一般的な手法を使用することです。サブプロセスはかなり接近しますが、プロセスが安全に対話する前にプロセスが終了するのを待たなければならないという事実は望ましくありません。

ドキュメントを見ると、直接操作できるstdin、stdout、およびstderrファイル記述子があると書かれていますが、「これを行わないでください」という大きな警告があります。残念ながら、この警告が存在する理由は完全には明らかではありませんが、Googleから収集したものは、OSバッファリングに関連していることであり、これらの内部バッファが失敗したときに予期せずデッドロックするコードを記述できる可能性があります(補足として、間違った方法を示し、正しい方法をいただければ幸いです)。

したがって、コードを潜在的なデッドロックの危険にさらすと、ポーリングを使用するか、実行中のプロセスを強制終了せずにインタラクティブに読み取るように選択するのが面白いかもしれないと思いました。私はクロスプラットフォームの能力を失いますが(私は思う)、それが追加のライブラリを必要としないという事実が好きです。しかし、もっと重要なことは、これがこれが良い考えであるかどうかを知りたいです。私はまだこのアプローチを試していませんが、プログラムを破壊する可能性のある落とし穴について心配しています。それは動作しますか?何をテストする必要がありますか?

私の特定のケースでは、プロセスに書き込むことができるかどうかについてはあまり心配していません。プロセスから繰り返し読み取るだけです。また、プロセスが大量のテキストをダンプすることはないと思うので、デッドロックの問題を回避したいと思いますが、それらの制限が何であるかを正確に知り、それがどこで壊れているかを確認するためのテストを作成できるようにしたいと思います。

4

4 に答える 4

3

Python2.6標準ライブラリ のマルチプロセッシングモジュールを使用します。

読み取りと書き込みの両方に使用できるQueueクラスがあります。

于 2009-07-10T21:16:58.833 に答える
1

これは別のスレッドで行い、メッセージキューを使用してスレッド間で通信します。私の場合、サブプロセスは%completeをstdoutに出力します。メインスレッドにかなりのプログレスバーを表示したかったのです。

 if sys.platform == 'win32':
        self.shell = False
        self.startupinfo = subprocess.STARTUPINFO()
        self.startupinfo.dwFlags = 0x01
        self.startupinfo.wShowWindow = 0
    else:
        self.shell = True
        self.startupinfo = None

。。。

f = subprocess.Popen( cmd, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE, env = env, shell = self.shell, startupinfo = self.startupinfo )
    f.stdin.close()
    line = ''
    while True:
        log.debug('reading')
        c = f.stdout.read(1)

        log.debug(c)

        if len(c) == 0:
            log.info('stdout empty; must be done')
            break;
        if ord(c) == 13:
            continue
        if c == '%':
            # post % complete message to waiting thread.
            line = ''
        else:
            line += c


    log.info('checking for errors')
    errs = f.stderr.readlines()

    if errs:
        prettyErrs = 'Reported Errors: '
        for i in errs:
            prettyErrs += i.rstrip('\n')

        log.warn( prettyErrs )
        #post errors to waiting thread
    else:
        print 'done'        
    return
于 2009-07-12T21:25:18.247 に答える
0

簡単に言うと、システムにその概念を設計することなしに、プロセス管理のための優れたクロスプラットフォームシステムのようなものはありません。これは特に標準ライブラリにあります。さまざまなUNIXバージョンでさえ、独自の互換性の問題があります。

最善の策は、すべてのプロセスを適切なイベント処理でインストルメント化して、どのIPCシステムがどのプラットフォームでも最適に機能することから発生するイベントに気付くことです。名前付きパイプは、説明する問題の一般的なルートになりますが、プラットフォームごとに実装の違いがあります。

于 2009-07-10T17:22:49.757 に答える
0

このトピックについての私の無知を許してください、しかしあなたはただ「バッファリングされていない」の-uフラグでpythonを起動することができませんでしたか?

これも興味深いかもしれません... http://www.gossamer-threads.com/lists/python/python/658167

于 2009-08-18T16:28:37.200 に答える