【问题标题】:Sharing a variable between processes在进程之间共享变量
【发布时间】:2012-04-09 00:23:27
【问题描述】:

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

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

【问题讨论】:

    标签: python map multiprocessing ctypes


    【解决方案1】:

    解决方案是引入新进程并传递共享的 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
    

    【讨论】:

    • 我仍然遇到同样的错误.. 但我无法引用 dummy 包.. 你确定这是你使用的确切代码吗?您不应该在initargs 参数中传递c_int 的值,而不是变量本身吗?
    【解决方案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,以及答案。

    【讨论】:

      【解决方案3】:

      当然,您可以在共享内存中使用共享的ctypes 值,如果您只想下载字节,则应该这样做。为每个工作人员传递相关值,调用进程将可以访问它。

      见: http://docs.python.org/library/multiprocessing.html#shared-ctypes-objects

      【讨论】:

      • 你无法映射 ctypes 共享对象:RuntimeError: Synchronized objects should only be shared between processes through inheritance
      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 2016-12-14
        • 2019-05-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-27
        • 1970-01-01
        相关资源
        最近更新 更多