在进程之间共享变量
问题描述:
我有一个可以并行下载多个文件的下载器函数。 我使用multiprocessing.Pool.map_async
为了下载同一文件的不同块。 我想显示下载的状态栏。为此,我需要知道已经下载的总字节数(total_bytes_dl
)。在进程之间共享变量
pool = multiprocessing.Pool(processes)
mapObj = pool.map_async(f, args)
while not mapObj.ready():
status = r"%.2f MB/%.2f MB" % (total_bytes_dl/1024.0/1024.0, filesize/1024.0/1024.0,)
status = status + chr(8)*(len(status)+1)
print status,
time.sleep(0.5)
有没有一种方法来设置,将所有这些过程和主要过程之间共享的变量,所以每一个过程可以追加刚刚下载的字节的数量?
答
的解决方案是intilize新的过程,并通过所述共享ctypes的值:
from ctypes import c_int
import dummy
shared_bytes_var = multiprocessing.Value(c_int)
def Func(...):
....
pool = multiprocessing.Pool(initializer=_initProcess,initargs=(shared_bytes_var,))
....
def _initProcess(x):
dummy.shared_bytes_var = x
答
当然,你可以在共享内存中使用共享的值,如果你只是想下载它应该做的字节。传递每个工作人员的相关价值,并且调用过程将有权访问它。
看到: http://docs.python.org/library/multiprocessing.html#shared-ctypes-objects
答
你可以使用多进程队列对象,工人可以用它来发送的状态数据。您的主进程必须从队列中读取状态条目并相应地更新状态。
答
使用分配这样的队列对象:
que = multiprocessing.Manager().Queue()
这个变量传递给工人,并且它们可以使用que.put(bytes)
至 定期报告他们自上次报告以来已经下载了多少。您 然后就检查队列的大小和拉在任何收到的报告:
downloaded = 0
while not mapObj.ready():
for _ in range(q.qsize()):
downloaded += q.get()
print downloaded, r"bytes downloaded\r",
time.sleep(0.5)
注:虽然模块还提供了一种方法multiprocessing.Queue()
,它不完全等同于multiprocessing.Manager().Queue()
。见this question,和答案。
你不能映射ctypes共享对象:'RuntimeError:同步对象只能通过继承在进程间共享' – iTayb 2012-03-24 23:41:24