使用管理器、池和共享列表的Python多处理并发不起作用
我正在学习python多处理,并尝试使用此功能填充一个包含操作系统中所有文件的列表。但是,我编写的代码只按顺序执行使用管理器、池和共享列表的Python多处理并发不起作用,python,concurrency,parallel-processing,multiprocessing,python-multiprocessing,Python,Concurrency,Parallel Processing,Multiprocessing,Python Multiprocessing,我正在学习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()
#!/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)
当我检查流程树时,我只能看到生成的单个流程。(man pstree说{}表示父进程产生的子进程。)
我要寻找的是,为每个tld目录生成一个进程,填充共享列表文件,根据目录的数量大约有10-15个进程。我做错了什么
编辑::
我使用multiprocessing.Pool
创建工作线程,这次
进程已生成,但在尝试使用multiprocessing.Pool.map()
时出现错误。我指的是python文档中显示的以下代码
from multiprocessing import Pool
def f(x):
return x*x
if __name__ == '__main__':
p = Pool(5)
print(p.map(f, [1, 2, 3]))
根据该示例,我将代码重写为
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---
但是代码是错误的
processpoolworker-2:
回溯(最近一次呼叫最后一次):
文件“/usr/lib/python2.7/multiprocessing/process.py”,第258行,在_bootstrap中
回溯(最近一次呼叫最后一次):
文件“/usr/lib/python2.7/multiprocessing/process.py”,第258行,在_bootstrap中
文件“/usr/lib/python2.7/multiprocessing/process.py”,第258行,在_bootstrap中
文件“/usr/lib/python2.7/multiprocessing/process.py”,第258行,在_bootstrap中
self.run()
文件“/usr/lib/python2.7/multiprocessing/process.py”,第114行,正在运行
自我目标(*自我参数,**自我参数)
worker中的文件“/usr/lib/python2.7/multiprocessing/pool.py”,第102行
文件“/usr/lib/python2.7/multiprocessing/process.py”,第114行,正在运行
task=get()
get中第376行的文件“/usr/lib/python2.7/multiprocessing/queues.py”
返回recv()
AttributeError:“模块”对象没有属性“获取文件”
自我目标(*自我参数,**自我参数)
self.run()
task=get()
文件“/usr/lib/python2.7/multiprocessing/process.py”,第114行,正在运行
self.run()
文件“/usr/lib/python2.7/multiprocessing/process.py”,第114行,正在运行
自我目标(*自我参数,**自我参数)
worker中的文件“/usr/lib/python2.7/multiprocessing/pool.py”,第102行
文件“/usr/lib/python2.7/multiprocessing/process.py”,第114行,正在运行
task=get()
get中第376行的文件“/usr/lib/python2.7/multiprocessing/queues.py”
AttributeError:“模块”对象没有属性“获取文件”
self.run()
我在这里做错了什么,为什么get_files()函数会出错?这只是因为您在定义函数之前实例化了池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)
进程的总体思想是,在启动它的那一刻,您就叉出主进程的内存。因此,在主进程中执行的任何定义都不会出现在子进程中
如果您想要共享内存,可以使用线程
库,但它会有一些问题(cf:)谢谢,这很有效。然而,我想知道,既然tld已经定义了,为什么在函数重要之前定义池呢?定义池时没有对函数的引用。在池中有一个:)。map
。通过使用pool.map
您要求您的流程使用函数get_files
。同意。但是pool.map是在函数之后定义的,eventhough pool是在函数之前定义的,因为根据python文档,在定义pool时,它只是要生成的工作进程数pool=pool(processs=4)#启动4个工作进程`请纠正我误解的地方。再次感谢@FunkySayuI,我不确定你是否理解了你这句话的全部意思(我的英语需要提高:)。据我所知,您认为池只设置进程的数量,而不启动进程。那不是真的(感谢上帝:D)。总体思路是启动池以便在之后使用它(例如,使用pool.map
)。初始化过程相当长(相信我,我在这方面做了很多工作),应该只运行一次。这非常有意义。无论你在英语中缺少什么,你都可以用Python来弥补:)太棒了。谢谢你的帮助。谢谢@FunkySayu:)
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)