4

マルチプロセッシングを実装してレプリケーション ループを高速化しようとしていますが、Python27 で動作させることができません。これは私のプログラムの非常に単純化されたバージョンであり、SO のドキュメントとその他の回答に基づいています (複数の引数に対する Python multiprocessing pool.map など)。マルチプロセッシングに関して多くの質問があることは認識していますが、これまでのところ、この問題を解決できていません。あまりにも些細なことを見落としていないことを願っています。

コード

import itertools
from multiprocessing import Pool

def func(g, h, i):
    return g + h + i

def helper(args):
    args2 = args[0] + (args[1],)
    return func(*args2)

pool = Pool(processes=4)
result = pool.map(helper, itertools.izip(itertools.repeat((2, 3)), range(20)))
print result

これは を使用している場合は機能しますが、 を使用している場合は機能しmap(...)ませんpool.map(...)

エラーメッセージ:

Process PoolWorker-3:
Traceback (most recent call last):
File "C:\Program_\EPD_python27\lib\multiprocessing\process.py", line 258, in _
bootstrap
self.run()
File "C:\Program_\EPD_python27\lib\multiprocessing\process.py", line 114, in run
self._target(*self._args, **self._kwargs)
File "C:\Program_\EPD_python27\lib\multiprocessing\pool.py", line 85, in worker
task = get()
File "C:\Program_\EPD_python27\lib\multiprocessing\queues.py", line 376, in get
return recv()
AttributeError: 'module' object has no attribute 'helper'
4

3 に答える 3

3

この問題は、次のmain()関数を追加することで解決されます。

import itertools
from multiprocessing import Pool

def func(g, h, i):
    return g + h + i

def helper(args):
    args2 = args[0] + (args[1],)
    return func(*args2)

def main():
    pool = Pool(processes=4)
    result = pool.map(helper,itertools.izip(itertools.repeat((2, 3)), range(10)))
    print result

if __name__ == '__main__':
    main()

@ErikAllik からの回答に基づいて、これは Windows 固有の問題である可能性があると考えています。

編集: これは、 Pythonでのマルチプロセッシングに関する明確で有益なチュートリアルです。

于 2013-10-02T10:28:49.100 に答える
1

私の OS X では、Python 2.7 を使用して、コードは次のように出力されます。

[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]

Python パスに が含まれていることがわかりますEPD_python27。そのため、Enthought Python ディストリビューションではなく、vanila Python ディストリビューションを使用してみてください。

更新: 解決策については、@fileunderwater の回答を参照してください。私は自分で一度これに遭遇しましたが、それを完全に忘れていました:)

説明: モジュールに最上位コードが含まれているため、問題が発生します (何らかの理由で Wi​​ndows でのみ発生しますが、OS X および Linux でも発生する可能性があります)。つまり、サブプロセスにコードをインポートしてmultiprocessing実行します。ただし、モジュールに最上位コードが含まれている場合は、モジュールがインポートされるとすぐに評価/実行されます。それをラップして条件付きで(つまり、ブロックを使用して)main呼び出すだけで、これが発生するのを防ぎます。また、これは OS X と Linux ではより正確であり、通常はコードをモジュールに直接配置するよりも常に好まれます。main()if __name__ == '__main__'

于 2013-10-02T10:13:02.133 に答える