Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python多处理-进程挂起连接,用于大型队列_Python_Process_Queue_Multiprocessing - Fatal编程技术网

python多处理-进程挂起连接,用于大型队列

python多处理-进程挂起连接,用于大型队列,python,process,queue,multiprocessing,Python,Process,Queue,Multiprocessing,我正在运行Python2.7.3,并注意到以下奇怪的行为。考虑这个极小的例子: from multiprocessing import Process, Queue def foo(qin, qout): while True: bar = qin.get() if bar is None: break qout.put({'bar': bar}) if __name__ == '__main__': i

我正在运行Python2.7.3,并注意到以下奇怪的行为。考虑这个极小的例子:

from multiprocessing import Process, Queue

def foo(qin, qout):
    while True:
        bar = qin.get()
        if bar is None:
            break
        qout.put({'bar': bar})

if __name__ == '__main__':
    import sys

    qin = Queue()
    qout = Queue()
    worker = Process(target=foo,args=(qin,qout))
    worker.start()

    for i in range(100000):
        print i
        sys.stdout.flush()
        qin.put(i**2)

    qin.put(None)
    worker.join()
当我循环超过10000次或更多次时,我的脚本将挂起
worker.join()
。当循环仅达到1000时,它工作正常


有什么想法吗?

子流程中的
qout
队列已满。您从
foo()
中放入的数据不适合内部使用的操作系统管道的缓冲区,因此子流程会阻止尝试容纳更多数据。但是父进程没有读取这些数据:它也只是被阻塞,等待子进程完成。这是一个典型的死锁。

队列的大小必须有限制。考虑以下修改:

from multiprocessing import Process, Queue

def foo(qin,qout):
    while True:
        bar = qin.get()
        if bar is None:
            break
        #qout.put({'bar':bar})

if __name__=='__main__':
    import sys

    qin=Queue()
    qout=Queue()   ## POSITION 1
    for i in range(100):
        #qout=Queue()   ## POSITION 2
        worker=Process(target=foo,args=(qin,))
        worker.start()
        for j in range(1000):
            x=i*100+j
            print x
            sys.stdout.flush()
            qin.put(x**2)

        qin.put(None)
        worker.join()

    print 'Done!'
它按原样工作(注释掉
qout.put
行)。如果您试图保存所有100000个结果,则
qout
变得太大:如果我取消注释
qout.put({'bar':bar})
中的
foo
,并将
qout
的定义保留在位置1,则代码挂起。但是,如果我将
qout
definition移到位置2,则脚本完成


所以简而言之,您必须小心
qin
qout
都不会变得太大。(另请参见:)

当我试图将字符串放入一个总大小约为5000 cahrs的队列时,我在
python3
上遇到了同样的问题

在我的项目中,有一个主机进程,它设置队列并启动子进程,然后加入。Afrer
join
主机进程从队列中读取数据。当子流程产生太多数据时,主机将启动
join
。我使用以下函数在主机进程中等待子进程修复了此问题:

来自多处理导入进程,队列
从队列导入空
def从_进程中生成_(q:队列,p:进程):
当p.活着时()
p、 加入(超时=1)
尽管如此:
尝试:
收益率q.get(block=False)
除空外:
打破
我从队列中读取数据,因为队列一填满,它就不会变得太大

在池关闭后,我试图
.get()
异步工作进程

带块外部的缩进错误

我有这个

我需要这个


如果您还提供了问题的代码解决方案,那就太好了。例如,如何清空缓冲区以使子进程不阻塞。什么是
清空
?请详细说明。我想在
with
块之后使用
get()
的结果。@MSS,退出with块会破坏池,这意味着所有作业结果都会被删除,因此您可以将它们复制到with块外部的变量/列表中,也可以在with块内部使用它们(或者根本不使用with块,完成后手动关闭池)
with multiprocessing.Pool() as pool:
    async_results = list()
    for job in jobs:
        async_results.append(
            pool.apply_async(
                _worker_func,
                (job,),
            )
        )
# wrong
for async_result in async_results:
    yield async_result.get()
with multiprocessing.Pool() as pool:
    async_results = list()
    for job in jobs:
        async_results.append(
            pool.apply_async(
                _worker_func,
                (job,),
            )
        )
    # right
    for async_result in async_results:
        yield async_result.get()