6

私はPythonマルチプロセッシングを学んでいます。この機能を使用して、osに存在するすべてのファイルをリストに入れようとしています。しかし、私が書いたコードは順番にしか実行していません。マネージャ、プール、共有リストを使用したPythonマルチプロセッシング同時実行性

#!/usr/bin/python 
import os 
import multiprocessing 
tld = [os.path.join("/", f) for f in os.walk("/").next()[1]] #Gets a top level directory names inside "/" 
manager = multiprocessing.Manager() 
files = manager.list() 


def get_files(x): 
    for root, dir, file in os.walk(x): 
     for name in file: 
      files.append(os.path.join(root, name)) 

mp = [multiprocessing.Process(target=get_files, args=(tld[x],)) 
     for x in range(len(tld))] 

for i in mp: 
    i.start() 
    i.join() 
print len(files) 

私はプロセスツリーをチェックしても、生成された単一のチリプロセスしか見ることができません。 (男性pstreeは親によって生成された子プロセスを表し} {言います。)

---bash(10949)---python(12729)-+-python(12730)---{python}(12752) 
           `-python(12750)` 

私は共有リストfilesを移入、各TLDのディレクトリのためのプロセスを起動するために、でしたを探していた、そしてそれは周りがどうなりますか10-15のプロセスは、ディレクトリの数によって異なります。私は間違って何をしていますか?

EDIT ::

私はワーカースレッドを作成するためにmultiprocessing.Poolを使用し、この時間が プロセスが起動されているが、私はmultiprocessing.Pool.map()を使用しようとすると、エラーを与えています。私はこの例に続い

from multiprocessing import Pool 
def f(x): 
return x*x 

if __name__ == '__main__': 
    p = Pool(5) 
    print(p.map(f, [1, 2, 3])) 

を示すPythonのドキュメントに以下のコードを参照し、Iは

import os 
import multiprocessing 
tld = [os.path.join("/", f) for f in os.walk("/").next()[1]] 
manager = multiprocessing.Manager() 
pool = multiprocessing.Pool(processes=len(tld)) 
print pool 
files = manager.list() 
def get_files(x): 
    for root, dir, file in os.walk(x): 
     for name in file: 
      files.append(os.path.join(root, name)) 
pool.map(get_files, [x for x in tld]) 
pool.close() 
pool.join() 
print len(files) 

としてコードを書き直し、それが複数のプロセスをフォークします。

---bash(10949)---python(12890)-+-python(12967) 
           |-python(12968) 
           |-python(12970) 
           |-python(12971) 
           |-python(12972) 
           ---snip--- 

しかし、コードが

Process PoolWorker-2: Traceback (most recent call last): File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap Traceback (most recent call last): File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap self.run() File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run self._target(*self._args, **self._kwargs) File "/usr/lib/python2.7/multiprocessing/pool.py", line 102, in worker File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run task = get() File "/usr/lib/python2.7/multiprocessing/queues.py", line 376, in get return recv() AttributeError: 'module' object has no attribute 'get_files' self._target(*self._args, **self._kwargs) self.run() task = get() File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run self.run() File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run self._target(*self._args, **self._kwargs) File "/usr/lib/python2.7/multiprocessing/pool.py", line 102, in worker File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run task = get() File "/usr/lib/python2.7/multiprocessing/queues.py", line 376, in get AttributeError: 'module' object has no attribute 'get_files' self.run()

を言っerroringさは、私がここで間違って何をやって、そしてなぜget_files()関数のエラーを出しますか?

答えて

3

あなたのプールが機能get_filesを定義する前にインスタンスので、それは単にです:

import os 
import multiprocessing 

tld = [os.path.join("/", f) for f in os.walk("/").next()[1]] 
manager = multiprocessing.Manager() 

files = manager.list() 
def get_files(x): 
    for root, dir, file in os.walk(x): 
     for name in file: 
      files.append(os.path.join(root, name)) 

pool = multiprocessing.Pool(processes=len(tld)) # Instantiate the pool here 

pool.map(get_files, [x for x in tld]) 
pool.close() 
pool.join() 
print len(files) 

プロセスの全体的なアイデアは、あなたがそれを起動した瞬間に、あなたはメインプロセスのメモリをforkということです。したがって任意の定義は、メインプロセスの後に実行されます。フォークはサブプロセスに含まれません。

あなたは、共有メモリを使用する場合は、あなたがthreadingライブラリを使用することができますが、あなたはそれでいくつかの問題を持っています(CF:The global interpreter lock

+0

は働いていたこと、ありがとうございます。しかし、tldはすでに定義されているので、関数が重要になる前にプールを定義していたのはなぜですか?プールを定義するときに関数への参照はありませんでした。 – nohup

+0

あなたの 'pool.map'には1つの:)があります。 'pool.map'を使うことによって、あなたのプロセスに' get_files'関数を使うように頼みます。 – FunkySayu

+0

合意。しかし、pool.mapは関数の後に定義されていましたが、プールを定義する間に、生成されるワーカープロセスの数になるため、前に定義されたeventhoughプールが前に定義されていました。 'プール=プール(プロセス= 4)#開始する4ワーカープロセス'私は誤解をどこに修正してください。もう一度、ありがとう@FunkySayu – nohup

関連する問題