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 つは、並行して実行される操作のリターン コードに簡単にアクセスできることです。
ありがとう