3

ライブラリ用のctypesラッパーがあります。残念ながら、このライブラリは100%信頼できるわけではありません(時折のsegfaultなど)。それがどのように使用されるかという理由で、私はラッパーがライブラリのクラッシュに対して適度に回復力があることを望んでいます。

これを行う最良の方法は、プロセスをフォークし、結果を子から送り返すことのようです。私はこれらの線に沿って何かをしたいです:

r, w = os.pipe()
pid = os.fork()

if pid == 0:
    # child
    result = ctypes_fn()
    os.write(w, pickle.dumps(result))
    os.close(w)
else:
    # parent
    os.waitpid(pid, 0)
    result = os.read(r, 524288) # can be this big
    os.close(r)

    return pickle.loads(result)

ただし、これは完全には機能しません。フォークされたプロセスは書き込みでハングします。一度に送信しすぎていませんか?この問題に対するより簡単な解決策はありますか?

4

3 に答える 3

4

おそらくあなたはパイプに収まるよりも多くのデータを書き込もうとしているので、誰かがやって来てそこからその情報の一部を読み取るまでブロックされています。唯一のリーダーは親プロセスであるため、これは決して起こりません。親プロセスは、子が終了するまで待ってから何かを読み取るように作成したように見えます。これは、デッドロックと呼ばれるものです。

そのos.waitpid呼び出しを取り除いて、何が起こるかを確認することを検討してください。もう1つのオプションは、os.pipeに、より大きなバッファーを提供するメソッドがあるかどうかを確認することです(私はあなたの環境を十分に理解していません)。

于 2009-04-16T17:45:01.283 に答える
2

基本的な問題は、パイプに64kBの制限があることです。単純なものから複雑なものまで、いくつかの可能な解決策:

  1. 送信するデータが少なくなります。zlib.compressは、制限を下回るのに役立つ可能性があります。
  2. パイプを使用して制御情報を送信するだけで、実際のデータを別の場所(file、mmap、memcache)に保存します。
  3. パイプを引き続き使用しますが、出力をチャンクします。2セットのパイプを使用して、プロセスが相互に通信し、通信を同期できるようにします。コードはより複雑ですが、それ以外の点では非常に効果的です。
于 2009-04-16T19:15:57.040 に答える
0

ted.dennisonが言及したデッドロックの1つの解決策は、次の擬似コードです。

#parent
while waitpid(pid, WNOHANG) == (0, 0):
    result = os.read(r, 1024)
    #sleep for a short time
#at this point the child process has ended 
#and you need the last bit of data from the pipe
result = os.read(r, 1024)
os.close(r)

WNOHANGオプションを指定したWaitpidを使用すると、子プロセスがまだ終了していない場合、waitpidがすぐに戻ります。この場合、(0,0)を返します。上記のコードのように、ループを通過するたびに結果変数を上書きしないようにする必要があります。

于 2009-04-16T19:15:38.583 に答える