我有一个Python程序基本上可以执行以下操作:
for j in xrange(200):
# 1) Compute a bunch of data
# 2) Write data to disk
1)大约需要2-5分钟 2)大约需要1分钟
请注意,内存中存储的数据太多。
理想情况下,我想要做的是以避免空闲CPU的方式将数据写入磁盘。这在Python中可行吗?谢谢!
答案 0 :(得分:9)
您可以尝试这样using multiple processes:
import multiprocessing as mp
def compute(j):
# compute a bunch of data
return data
def write(data):
# write data to disk
if __name__ == '__main__':
pool = mp.Pool()
for j in xrange(200):
pool.apply_async(compute, args=(j, ), callback=write)
pool.close()
pool.join()
pool = mp.Pool()
将创建一个工作进程池。默认情况下,worker的数量等于您的计算机具有的CPU核心数。
每个pool.apply_async调用将由工作进程池中的工作者运行的任务排队。当工作人员可用时,它将运行compute(j)
。当worker返回一个值data
时,主进程中的一个线程运行回调函数write(data)
,其中data
是工作者返回的数据。
一些警告:
j
,范围从0到199.解决此问题的一种方法
将数据写入sqlite(或其他类型)数据库
将j
作为数据字段之一。然后,当你想阅读
按顺序排列的数据,您可以SELECT * FROM table ORDER BY j
。使用多个进程会增加所需的内存量 因为数据是由工作进程生成的,等待写入磁盘的数据会累积在队列中。您 可能能够减少使用NumPy所需的内存量 阵列。如果那是不可能的,那么你可能不得不减少 进程数:
pool = mp.Pool(processes=1)
这将创建一个工作进程(运行compute
),离开
运行write
的主要流程。由于compute
需要更长时间
write
,队列不会备份超过一个块
要写入磁盘的数据。但是,您仍然需要足够的内存
在写一个不同的块时计算一个数据块
数据到磁盘。
如果您没有足够的内存同时执行这两项操作,那么您别无选择 - 您的原始代码是顺序运行compute
和write
的唯一方法。
答案 1 :(得分:3)
您可以使用Queue.Queue
(模块位于此处:Queue)和threading.Thread
(或threading.start_new_thread
,如果您只需要一个功能),模块是这里:threading - 由于文件写入不是CPU密集型并且使用更多IO。 (并且GIL不会影响它)。
答案 2 :(得分:2)
简单的方法是只使用线程和队列。另一方面,如果计算部分不依赖于全局状态,并且您的计算机具有多个CPU核心,则使用process pool
的效率更高。from multiprocessing import Pool
def compute_data(x):
return some_calculation_with(x)
if __name__ == '__main__':
pool = Pool(processes=4) # let's say you have quad-core, so start 4 workers
with open("output_file","w") as outfile:
for calculation_result in pool.imap(compute_data, range(200)):
# pool.imap returns results as they come from process pool
outfile.write(calculation_result)