4

仕事の出力を Manager リストに追加しようとするワーカーのプールをセットアップする単純な python マルチプロセッシング スクリプトがあります。このスクリプトには 3 つのコール スタックがあります。スクリプトをデバッグしようとすると (偶然にも Windows 7/64 ビット/VS 2010/PyTools で)、スクリプトはネストされたプロセス作成ループに突入し、無数のプロセスが生成されます。誰でも理由を特定できますか?私は非常に単純なものが欠けていると確信しています。問題のあるコードは次のとおりです: -

import multiprocessing
import logging

manager = multiprocessing.Manager()
results = manager.list()

def g1(x):
    y = x*x
    print "processing: y = %s" % y
    results.append(y)

def f1():
    logger = multiprocessing.log_to_stderr()
    logger.setLevel(multiprocessing.SUBDEBUG)

    pool = multiprocessing.Pool(processes=4)
    for (i) in range(0,15):
        pool.apply_async(g1, [i])
    pool.close()
    pool.join()

def main():
    f1()

if __name__ == "__main__":
    main()

PS: multiprocessing.freeze_support()main に追加しようとしましたが、役に立ちませんでした。

4

1 に答える 1

6

基本的に、sr2222 がコメントで述べていることは正しいです。multiprocessing manager docsから、 ____main____ モジュールは子によってインポート可能でなければならないと書かれています。各マネージャーの「オブジェクトは、生成された子プロセスに対応する」ため、各子は基本的にモジュールを再インポートしています(修正されたバージョンにモジュールスコープでprintステートメントを追加することで確認できます!)...これは無限再帰につながります。

1 つの解決策は、マネージャー コードを f1() に移動することです。

import multiprocessing
import logging

def g1(results, x):
    y = x*x
    print "processing: y = %s" % y
    results.append(y)

def f1():
    logger = multiprocessing.log_to_stderr()
    logger.setLevel(multiprocessing.SUBDEBUG)
    manager = multiprocessing.Manager()
    results = manager.list()
    pool = multiprocessing.Pool(processes=4)
    for (i) in range(0,15):
        pool.apply_async(g1, [results, i])
    pool.close()
    pool.join()


def main():
    f1()

if __name__ == "__main__":
    main()
于 2012-08-13T16:54:23.293 に答える