在进程之间共享变量

时间:2012-03-24 22:28:57

标签: python map multiprocessing ctypes

我有一个下载器功能可以并行下载多个文件。 我使用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)

有没有办法设置一个将在所有这些进程和主进程之间共享的变量,因此每个进程都可以附加刚刚下载的字节数?

4 个答案:

答案 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)

您可以使用工作人员可用于发送状态数据的多进程队列对象。您的主进程必须从队列中读取状态条目并相应地更新状态。