Python 2.7 numpy和multiprocessing.process的奇怪行为

Python 2.7 numpy和multiprocessing.process的奇怪行为,python-2.7,numpy,multiple-processes,Python 2.7,Numpy,Multiple Processes,对不起,代码太长了,我已经尽力使它尽可能简单,但又不可复制 简而言之,这个python脚本启动四个进程,将数字随机分配到列表中。然后,将结果添加到一个多处理.Queue() 所有进程都在队列后运行print“。但是,它不会到达打印“结束”行。奇怪的是,如果我将arange从10001更改为1001,它就结束了。发生了什么事?我将把我的评论扩展成一个简短的回答。因为我也不理解这种奇怪的行为,所以这只是一种解决办法 第一个观察结果是,如果queue.put行被注释掉,代码将一直运行到末尾,因此这一定

对不起,代码太长了,我已经尽力使它尽可能简单,但又不可复制

简而言之,这个python脚本启动四个进程,将数字随机分配到列表中。然后,将结果添加到一个
多处理.Queue()


所有进程都在队列后运行
print“。但是,它不会到达
打印“结束”
行。奇怪的是,如果我将
arange
10001
更改为
1001
,它就结束了。发生了什么事?

我将把我的评论扩展成一个简短的回答。因为我也不理解这种奇怪的行为,所以这只是一种解决办法

第一个观察结果是,如果queue.put行被注释掉,代码将一直运行到末尾,因此这一定是与队列相关的问题。结果实际上是添加到队列中的,因此问题一定是队列和联接之间的相互作用

以下代码按预期工作

import random
import multiprocessing
import numpy
import sys
import time

def work(subarray, queue):
    result = [numpy.array([], dtype=numpy.uint64) for i in range (4)]

    for element in numpy.nditer(subarray):
        index = random.randint(0, 3)
        result[index] = numpy.append(result[index], element)

    queue.put(result)
    print("after the queue.put")


jobs = []
queue = multiprocessing.Queue()

subarray = numpy.array_split(numpy.arange(1, 15001, dtype=numpy.uint64), 4)


for i in range(4):
    process = multiprocessing.Process(target=work, args=(subarray[i], queue))
    jobs.append(process)
    process.start()

res = []
while len(res)<4:
    res.append(queue.get())

print("the end")
随机导入
导入多处理
进口numpy
导入系统
导入时间
def工作(子阵列、队列):
范围(4)中的i的结果=[numpy.array([],dtype=numpy.uint64)]
对于numpy.nditer(子阵列)中的元素:
索引=random.randint(0,3)
结果[index]=numpy.append(结果[index],元素)
queue.put(结果)
打印(“在queue.put之后”)
工作=[]
队列=多处理。队列()
子数组=numpy.array\u split(numpy.arange(115001,dtype=numpy.uint64),4)
对于范围(4)中的i:
process=multiprocessing.process(target=work,args=(子数组[i],队列))
jobs.append(进程)
process.start()
res=[]

而len(res)大多数子进程阻塞了put调用。

如有必要,阻塞,直到有空闲插槽可用

这可以通过在加入之前添加对queue.get()的调用来避免

此外,在多处理代码中,请通过以下方式隔离父进程:

if __name__ == '__main__':
    # main code here
这就是原因:

请记住,将项目放入队列的进程将在终止之前等待,直到“feeder”线程将所有缓冲项目馈送到底层管道。(子进程可以调用队列的cancel\u join\u thread()方法来避免这种行为。)

这意味着,无论何时使用队列,都需要确保在加入流程之前,已放入队列的所有项目最终都将被删除。否则,您无法确保将项目放入队列的进程将终止。还要记住,非守护进程将自动加入


我可以在python3.6上重现这种行为。我也不知道发生了什么。这种行为很奇怪。一个简单的解决方法是只从队列末尾收集结果,而不是加入。@Jannick我没有得到“在末尾代替加入”的答案。你能描述一下这一部分吗?我认为只有在队列中设置了最大大小时,put才会阻塞,这里不是这样。
if __name__ == '__main__':
    # main code here