[英]Failed to get data in another child from prom parent process in multiprocessing python
如果我声明一个 Queue object 全局级别并且我没有将它传递给多处理中的目标 function 并将一些数据放入 Queue object 并且无法进入主线程。 当我的进程在队列 object 中调用 get 方法时,它处于连续循环中,因为它正在等待队列 object 中的一些数据。
from multiprocessing import Process, Queue
def getretsults(*kwargs):
print("Executing Get Results..........")
res = []
for i in kwargs[0]:
res.append(i**i)
if len(kwargs) >= 1:
q = kwargs[1]
print(f"{id(q) = }")
q.put(res)
q = Queue()
def main_process():
a =256
b = 900
print("Executing Main Process.........")
args = [
range(1,6),
range(6,11),
range(11,16)
]
print(f"{id(args) = }")
process_ = []
if __name__ == '__main__':
q = Queue()
for x in args:
p = Process(target=getretsults, args=(x,))
process_.append(p)
p.start()
for x_ in process_:
x_.join()
print(q.get())
main_process()
我问过你在什么操作系统下运行,但没有收到回复。 我一开始会假设它是一个使用fork方法创建子进程的平台(比如Linux)。 我将展示第二个版本,它可以在 Linux 或 Windows 下运行。
您的代码有几个问题,有些是次要的,有些是主要的。
getresults
的参数名称是kwargs并且表示传递的所有位置参数的可迭代(元组)。 这是一个小问题(不是导致错误的任何原因),但约定是将此参数命名为args并使用名称kwargs来接收关键字参数。q
声明为全局的,子进程将继承对此队列实例的引用。 相反,您也可以创建一个非全局队列并将其作为参数传递。 但是在main_process
中你有q = Queue()
而你没有声明q
全局。 这导致创建一个新的局部变量q
并且没有将这个新队列实例分配给全局q
变量。 因此,放置结果的q
与主进程从中获取的q
不同。 这是一个主要错误。get
检索所有元素之前,您绝不能join
将元素放入多处理队列的子进程。 否则,您可能会挂起,因为在检索到这些元素之前,子进程通常无法终止。print(f"{id(args) = }")
完成什么。 如果您正在尝试打印 ID,则可能是print(f"id(args} = {id(args)}")
。getresults
你的测试if len(kwargs) >= 1:
应该是if len(kwargs) > 1:
。getresults
,取决于队列实例是否已作为第二个参数传递,应该确定您是将结果放入传递的队列参数还是已声明的全局队列。q = Queue()
,因此每个子进程肯定会彼此放入不同的队列,并且主进程正在执行的队列与之相反。通过这些更正,我们最终得到:
仅限 Linux 版本
from multiprocessing import Process, Queue
q = Queue()
def getretsults(*args):
print("Executing Get Results..........")
res = []
for i in args[0]:
res.append(i**i)
if len(args) > 1: # Must be >, not >=
result_q = args[1]
else:
result_q = q # global q
print(f'id(result_q) = {id(result_q)}')
result_q.put(res)
def main_process():
global q
a =256
b = 900
print("Executing Main Process.........")
args = [
range(1,6),
range(6,11),
range(11,16)
]
print(f"id(args) = {id(args)}")
process_ = []
q = Queue()
for x in args:
p = Process(target=getretsults, args=(x,))
process_.append(p)
p.start()
for _ in range(len(args)):
print(q.get())
for x_ in process_:
x_.join()
main_process()
印刷:
Executing Main Process.........
id(args) = 140481897185024
Executing Get Results..........
id(result_q) = 140481897250768
Executing Get Results..........
id(result_q) = 140481897250768
Executing Get Results..........
id(result_q) = 140481897250768
[1, 4, 27, 256, 3125]
[285311670611, 8916100448256, 302875106592253, 11112006825558016, 437893890380859375]
[46656, 823543, 16777216, 387420489, 10000000000]
独立于操作系统的版本
from multiprocessing import Process, Queue
def getretsults(x, q):
print("Executing Get Results..........")
res = []
for i in x:
res.append(i**i)
print(f'id(q) = {id(q)}')
q.put(res)
def main_process():
a =256
b = 900
print("Executing Main Process.........")
args = [
range(1,6),
range(6,11),
range(11,16)
]
print(f"id(args) = {id(args)}")
process_ = []
q = Queue()
for x in args:
p = Process(target=getretsults, args=(x, q))
process_.append(p)
p.start()
for _ in range(len(args)):
print(q.get())
for x_ in process_:
x_.join()
if __name__ == '__main__':
main_process()
印刷:
Executing Main Process.........
id(args) = 1775036479808
Executing Get Results..........
id(q) = 2365890922528
Executing Get Results..........
id(q) = 2128150562848
Executing Get Results..........
id(q) = 2368897255456
[46656, 823543, 16777216, 387420489, 10000000000]
[285311670611, 8916100448256, 302875106592253, 11112006825558016, 437893890380859375]
[1, 4, 27, 256, 3125]
请注意,队列的 id 对于每个子进程都是不同的,并且子进程将结果放入队列的顺序是不同的,并且不能依赖于使用显式Process
实例放入队列。
使用多处理池的版本
这里我们可以保证返回结果的顺序(注意我包括了一些代码改进):
from multiprocessing import Pool
# Renamed worker function:
def getresults(x):
print("Executing Get Results..........", flush=True)
return [i ** i for i in x] # More efficiently expressed!
def main_process():
print("Executing Main Process.........", flush=True)
args = [
range(1,6),
range(6,11),
range(11,16)
]
with Pool(3) as pool:
results = pool.map(getresults, args)
for result in results:
print(result)
if __name__ == '__main__':
main_process()
印刷:
Executing Main Process.........
Executing Get Results..........
Executing Get Results..........
Executing Get Results..........
[1, 4, 27, 256, 3125]
[46656, 823543, 16777216, 387420489, 10000000000]
[285311670611, 8916100448256, 302875106592253, 11112006825558016, 437893890380859375]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.