これは以前に回答されたことは知っていますが、スクリプト「python filename.py」を直接実行しても機能しないようです。 SuSE Linuxでは、Python 2.6.2です。
コード:
#!/usr/bin/python
# -*- coding: utf-8 -*-
from multiprocessing import Pool
p = Pool(1)
def f(x):
return x*x
p.map(f, [1, 2, 3])
コマンドライン:
> python example.py
Process PoolWorker-1:
Traceback (most recent call last):
File "/usr/lib/python2.6/multiprocessing/process.py", line 231, in _bootstrap
self.run()
File "/usr/lib/python2.6/multiprocessing/process.py", line 88, in run
self._target(*self._args, **self._kwargs)
File "/usr/lib/python2.6/multiprocessing/pool.py", line 57, in worker
task = get()
File "/usr/lib/python2.6/multiprocessing/queues.py", line 339, in get
return recv()
AttributeError: 'module' object has no attribute 'f'
Poolのインスタンスを作成する前に、f()
関数が定義されるようにコードを再構築します。そうしないと、ワーカーは関数を見ることができません。
#!/usr/bin/python
# -*- coding: utf-8 -*-
from multiprocessing import Pool
def f(x):
return x*x
p = Pool(1)
p.map(f, [1, 2, 3])
これは動作します:
#!/usr/bin/python
# -*- coding: utf-8 -*-
from multiprocessing import Pool
def f(x):
return x*x
if __== "__main__":
p = Pool(1)
p.map(f, [1, 2, 3])
あなたのコードが機能しない理由は100%わかりませんが、multiprocessing
モジュールによって起動された子プロセスはメインモジュールをインポートしようとするためです(定義したメソッドにアクセスするため)そしてその if __== "__main__"
スタンザは、プールをセットアップした初期化コードを実行しないために必要です。
1つの可能性は、pythonファイルがモジュールと同じ名前を持つことです:
pickle.pyには、次のエラーがあります。
def find_class(self, module, name):
# Subclasses may override this
__import__(module)
mod = sys.modules[module] # <- here mod will reference your test/__init__.py
klass = getattr(mod, name)
return klass
これは、p = Pool(1)
を使用して、メインプロセスが関数fを作成する前にプロセス(スレッドとプロセス)をフォークするという事実に由来します。 Bartoszの回答で述べたように、生成されたプロセスは新しい関数にアクセスできません。
def f1(x):
...
p = Pool(1) # p is spawned and is now an independent process, knows f1
def f(x): # p doesn't not share this object
...
私が抱えていた問題は、タマスが指摘したif __== "__main__"
を使用することで解決しました。 Eclipse for Windowsでは、サンプルはインタープリターでは機能しません。これは http://docs.python.org/2/library/multiprocessing で説明されています