我有一个下载器功能可以并行下载多个文件。
我使用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)
有没有办法设置一个将在所有这些进程和主进程之间共享的变量,因此每个进程都可以附加刚刚下载的字节数?
答案 0 :(得分:4)
解决方案是初始化新进程并传递共享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
答案 1 :(得分:2)
使用像这样分配的队列对象:
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和答案。
答案 2 :(得分:1)
当然,您可以在共享内存中使用共享ctypes
值,如果您只是想要下载它应该执行的字节。传递每个工作者的相关值,并且调用进程可以访问它。
请参阅: http://docs.python.org/library/multiprocessing.html#shared-ctypes-objects
答案 3 :(得分:0)
您可以使用工作人员可用于发送状态数据的多进程队列对象。您的主进程必须从队列中读取状态条目并相应地更新状态。