我有使用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
函数内部的字符串时,似乎对主数组没有影响。
知道是什么问题吗?
答案 0 :(得分:0)
首先调用非阻塞函数p.start()
不足以保证在下一次调用之前调用jobs.remove()
。
第二,即使您要求显式p.join()
作为循环的最后一行代码,jobs
也可能在OS上的派生过程中被深度复制,因此,第一次迭代有效地删除了第一个条目,第二个条目获得具有一个条目的作业版本,因此它仅从自己的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
答案 1 :(得分:0)
您不能在流程之间共享可修改的标准数据结构。您必须使用队列/管道在进程之间进行通信,或者使用https://docs.python.org/3/library/multiprocessing.html#sharing-state-between-processes
中所述的基于内存映射的数据结构答案 2 :(得分:0)
严格来说,这不是问题的答案,但我没有发表评论而不是回答的声誉,因此我必须将其放在此处。
似乎您正在重建Python的concurrent.futures模块的许多功能。您最好改用它。它允许您创建具有最多进程数(在您的情况下为5个)的进程池,然后将作业传递给该池,作业将把它们交给可用的进程,或者将它们放入队列,直到某个进程可用为止。 / p>
您可能会使用类似如下的代码来实现所需的功能:
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}')