2

Python 3.2 (Fedora Core 14 64b) で実行されている Web サービス サーバーがありましたが、新しい依存関係 (3.2 をサポートしていない) のため、Python 2.6.7 へのバックポートを余儀なくされました。multiprocessing.Pool を使用していくつかの重要なセクションを並行して実行するように書き直された並行先物を使用していたコードのセクションがあります。コードは次のようになります。

import multiprocessing
def _run_threads(callable_obj, args, threads):
    pool = multiprocessing.Pool(processes=threads)
    process_list = [pool.apply_async(callable_obj, a) for a in args]
    pool.close()
    pool.join()
    return [x.get() for x in process_list]

「スレッド」という名前の紛らわしい乱用についてお詫び申し上げます。これらはプロセスです。

この関数を実装してから、時々ハングすることがわかりました。最終的に親 (マスター) プロセスを強制終了すると、文字化けしたトレースバックが返されます。ただし、重要と思われる行がいくつかあります。

[snip]
Process PoolWorker-445:
[snip]
File "/usr/lib64/python2.6/multiprocessing/pool.py", line 59, in worker
task = get()
File "/usr/lib64/python2.6/multiprocessing/queues.py", line 352, in get
return recv()
racquire()
[snip]

利用可能な証拠から、プール内の子プロセスが親プロセスからの「クローズ」シグナルの受信に失敗しているため、作業を待っているように思えます。親は座って子供がシャットダウンするのを待ちます。サーバーがハングします。これは非決定論的に発生しますが、このような重要なサーバーには頻繁に発生します (1 日に 1 回)。

run_threads() 関数のコーディングに問題はありますか? これは既知の問題であり、既知の回避策がありますか? 明らかに、タイムクリティカルな処理にこれを使用しているため、絶対に必要でない限り、順次実行用に再コーディングすることは好まれません。multiprocessing.Pool に固執する理由の 1 つは、並行して実行される操作のリターン コードに簡単にアクセスできることです。

ありがとう

4

1 に答える 1

0

この問題の原因がどこにあるのかわかりません。それは間違いなく非常に興味深いです。ただし、少し再構築するだけで問題が解決する場合があります。結果を収集する前にプール プロセスを終了する必要はないと思いますよね? 文書化されているように、プールを使用する「標準的な」方法に固執すると、次のようになります。

result = pool.apply_async(time.sleep, (10,))
print result.get(timeout=1)           # raises TimeoutError

または、あなたの場合、x.get() for x in process_listプールを閉じる/参加する前に呼び出します。問題が持続し、 の間get()に発生する場合、少なくとも とは関係がないことがわかりますclose()

于 2012-09-18T21:51:29.507 に答える