我正在并行读取+1000个〜200Mb CSV并使用pandas保存修改后的CSV。这会产生许多僵尸进程,累积到+ 128Gb的RAM,从而破坏性能。
csv_data = []
c = zip(a, b)
process_pool = Pool(cpu_count())
for name_and_index in process_pool.starmap(load_and_process_csv, c):
csv_data.append(name_and_index)
process_pool.terminate()
process_pool.close()
process_pool.join()
这是我目前的解决方案。在您处理超过80个CSV之前,它似乎不会导致问题。
PS:即使游泳池完成了〜仍然占用了96Gb的RAM,你可以看到python进程占用RAM但没有做任何事情也没有被破坏。此外,我确切地知道池正在执行的功能正在运行完成。我希望它具有足够的描述性。
答案 0 :(得分:4)
Python的multiprocessing
模块是基于流程的。所以你有很多过程是很自然的。
更糟糕的是,这些进程不共享内存,而是通过pickling/unpickling
进行通信。因此,如果需要在处理之间传输大数据,它们会非常慢,这就发生在这里。
对于这种情况,由于处理与I/O
相关,如果threading
是瓶颈,则使用I/O
模块的多线程可能会有更好的性能。线程共享内存,但它们也“共享”1个CPU内核,所以不能保证运行得更快,你应该尝试一下。
更新:如果多线程无效,则您没有多少选项。因为这种情况完全违背了Python并行处理架构的关键弱点。您可能想尝试dask(并行pandas):http://dask.readthedocs.io/en/latest/
答案 1 :(得分:0)
问题:
process_pool = Pool(48) for name_and_index in process_pool.starmap(load_and_process_csv, c):
我尝试了您的示例代码,但我无法启动更多一个 process
。
您的代码看起来非同寻常,除此Pool(48)
之外,processes
也很多。
要开始超过一个 process
,我必须更改为
process_pool = Pool(2)
c_list = [(a,b), (a,b)]
csv_data = process_pool.starmap(load_and_process_csv, c_list)
Python»3.6.1文档 multiprocessing.pool.Pool.starmap
starmap(func,iterable [,chunksize])
与map()类似,只是迭代的元素应该是作为参数解包的迭代。 因此,[(1,2),(3,4)]的可迭代导致[func(1,2),func(3,4)]。
由于我对(a, b)
一无所知,请仔细检查以下内容是否适用于您。
Python»3.6.1文档 multiprocessing.html#all-start-methods
明确地将资源传递给子进程 在使用fork start方法的Unix上,子进程可以使用全局资源在父进程中创建的共享资源。但是,最好将对象作为参数传递给子进程的构造函数。 除了使代码(可能)与Windows和其他启动方法兼容之外,这还确保只要子进程仍处于活动状态,对象就不会在父进程中进行垃圾回收。如果在父进程中对对象进行垃圾回收时释放某些资源,这可能很重要。
<强>问题强>:
我确切地知道池正在执行的功能正在运行完成。终止()
Stops the worker processes immediately without completing outstanding work.
请解释一下,为什么打电话给process_pool.terminate()
?