繁体   English   中英

Python 多处理进程共享数组

[英]Python Multiprocessing Process Shared Array

我有使用Process的 python 代码:

def RunCode(jobs):
    jobs.remove(multiprocessing.current_process().name)
    print("Name: {}".format(multiprocessing.current_process().name))
    print("len: {}".format(len(jobs)))

def randomString(stringLength=10):
    """Generate a random string of fixed length """
    letters = string.ascii_lowercase
    return ''.join(random.choice(letters) for i in range(stringLength))

if __name__ == '__main__':
    jobs = []

    while True:
        if len(jobs) < 5:
            p = multiprocessing.Process(target=RunCode,args=(jobs,),name="process-camera-{}".format(randomString())) 
            jobs.append(p.name)
            p.start()

我想在进程之间共享jobs数组,因此运行的进程不会超过 5 个。 但似乎当我删除RunCode function 中的字符串时不会影响主数组。 知道有什么问题吗?

首先调用非阻塞 function p.start()不足以保证在下次调用之前调用jobs.remove()

其次,即使您要求显式p.join()作为循环中的最后一行代码, jobs可能在您的操作系统上的 fork 期间被深度复制,因此第一次迭代有效地删除了第一个条目,第二个得到具有一个条目的作业版本,因此它仅从其自己的join副本中删除自己并显示一个条目,依此类推...

这段代码更清楚一点:

import multiprocessing
import string
import random

def RunCode(jobs):
    print("Name: {}".format(multiprocessing.current_process().name))
    print("len: {}".format(len(jobs)))
    jobs.remove(multiprocessing.current_process().name)
    print("len: {}".format(len(jobs)))

def randomString(stringLength=10):
    """Generate a random string of fixed length """
    letters = string.ascii_lowercase
    return ''.join(random.choice(letters) for i in range(stringLength))

if __name__ == '__main__':
    jobs = []

    while True:
        if len(jobs) < 5:
            p = multiprocessing.Process(target=RunCode,args=(jobs,),name="process-camera-{}".format(randomString())) 
            jobs.append(p.name)
            p.start()
            p.join()

输出:

Name: process-camera-xdmlyloget
len: 1
len: 0
Name: process-camera-whwgmxbgrs
len: 2
len: 1
Name: process-camera-jbhzrsdtqg
len: 3
len: 2
Name: process-camera-oprinyvlkl
len: 4
len: 3
Name: process-camera-kyaafxiaoz
len: 5
len: 4

您不能在进程之间共享可修改的标准数据结构。 您必须使用队列/管道在进程之间进行通信,或者使用https://docs.python.org/3/library/multiprocessing.html#sharing-state-between-processes中描述的基于内存映射的数据结构

严格来说,这不是问题的答案,但我没有发表评论而不是答案的声誉,所以我必须把它放在这里。

看起来您正在重建 Python 的concurrent.futures模块的很多 function。 改用它可能会更好。 它允许您创建一个具有最大进程数(在您的情况下为 5 个)的进程池,然后将作业传递给该池,该池会将它们交给可用的进程或将它们放入队列中,直到有可用的进程。

您可能会使用如下所示的代码来实现您所需要的:

from concurrent import futures

def do_thing(arg):
    """This is where you do the thing you want done in other processes."""
    return arg, arg ** arg

ex = futures.ProcessPoolExecutor(max_workers=5)

done = []

for i in range(100):
    done.append(ex.submit(do_thing, i))

for thing in done:
    num, exp = thing.result()
    print(f'{num}**{num} = {exp}')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM