Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/310.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_Parallel Processing_Multiprocessing_Zombie Process - Fatal编程技术网

Python 为什么即使对池的映射调用完成,进程也要花费很长时间才能加入?

Python 为什么即使对池的映射调用完成,进程也要花费很长时间才能加入?,python,parallel-processing,multiprocessing,zombie-process,Python,Parallel Processing,Multiprocessing,Zombie Process,这是关于python3.5中的多处理模块的另一个问题。我的问题是,我知道所有的forked processed都完成了它们的工作(我可以在队列中看到它们的结果),AsyncResult.result()返回True,这意味着作业已经完成,但当我继续使用PoolObj.join()时,它将花费永远的时间。我知道我可以用PoolObj.terminate()继续我的生活,但我想知道为什么会发生这种情况 我正在使用以下代码: def worker(d): queue.put(d) def g

这是关于
python3.
5中的
多处理
模块的另一个问题。我的问题是,我知道所有的forked processed都完成了它们的工作(我可以在
队列中看到它们的结果),AsyncResult.result()返回True,这意味着作业已经完成,但当我继续使用PoolObj.join()时,它将花费永远的时间。我知道我可以用PoolObj.terminate()继续我的生活,但我想知道为什么会发生这种情况

我正在使用以下代码:

def worker(d):
    queue.put(d)

def gen_data():
    for i in range(int(1e6)):
        yield i

if __name__ == "__main__":
    queue = Queue(maxsize=-1)
    pool = Pool(processes=12)
    pool_obj_worker = pool.map_async(worker, gen_data(), chunksize=1)
    pool.close()

    print ('Lets run the workers...\n')
    while True:
        if pool_obj_worker.ready():
            if pool_obj_worker.successful():
                print ('\nAll processed successfully!') # I can see this quickly, so my jobs are done
            else:
                print ('\nAll processed. Errors encountered!')
            sys.stdout.flush()
            print (q.qsize()) # The size is right that means all workers have done their job
            pool.join() # will get stuck here for long long time
            queue.put('*')           
            break
    print ('%d still to be processed' %
           pool_obj_worker._number_left)
    sys.stdout.flush()
    time.sleep(0.5)

我做错了吗?请开导我。或者持有
join()
的进程已经僵化了吗?

这里的问题是,您在工作进程中使用了一个额外的
队列,而不是由
池完成的队列。
当进程完成其工作时,它们都将加入
多处理.Queue
中使用的
FeederThread
,这些调用将挂起(可能是因为所有线程同时调用
join
,并且可能存在一些奇怪的争用条件,不容易调查)

multiprocessing.util.log\u添加到\u stderr(10)
中,可以显示您的进程在加入队列联接线程时挂起


要解决您的问题,您可以使用
多处理.SimpleQueue
而不是
多处理.Queue
(没有挂接连接,因为没有联接线程),或者尝试使用方法
pool.unordered_imap
,该方法提供与您似乎实现的行为相同的行为(返回包含worker返回的结果的无序生成器).

如果您减少要放入队列的内容的大小,会发生什么情况?问题甚至存在于较小的值1e5和1e4。但是,对于小于这些值的值,问题并不明显。将其减少到
10
并尝试-它至少完成了还是仍然挂起?这可能与此有关,我也有类似的问题lem但是使用
进程
。虽然在您的情况下,您说队列大小正确,因此可能会发生其他事情,但这可能会使您朝着正确的方向前进。另外,如果没有
,会发生什么事。join()
有吗?即使有10个,也要加入暂停10秒。我正在使用12个进程,即使从
pool\u obj\u worker.successful()收到
True
后,也可以在进程监视器中看到它们
如果我使用
collections.deque
代替
多处理.Queue
,问题会得到解决,但没有用,因为我无法返回结果。我想每个fork都会初始化一个新的deque实例。谢谢Thomas。你说得对!加入队列会带来巨大的开销。如果使用pool,我如何监控作业的进度.imap_无序?这里还有一个相关问题!为什么imap生成器上的迭代会随着时间的推移而变慢。这是由于在列表中累积结果的影响吗?如果是这样,我如何解决这个问题?要监视进度,可以尝试访问
IMAPUNORDEDITOR。_index
我看不到此处提供的代码有任何减速。Each当您访问生成器的某个元素时,它将从列表中删除,因此如果它处于平衡状态,则不会真正减速。可能您的对象比
int
大,并且生成器会变大。这取决于您的使用情况。。