很多人在使用Python的多进程过程,会用的进程的Queue来完成进程间的数据安全传递,因为Queue是进程内安全的,读写过程不用自己单独加锁和解锁,但是有一种情况就是Queue的在多进程里如果一直添加,会导致进程卡死,join永不退出进程,无限执行模式,具体Queue.put()的调度到多少个,没有做实验,但是1000内以内的可以忽略下面的讲解,因为只有数量够大才会将进程卡死,比如下面的代码 执行的效果就是
from multiprocessing import Queue,Process
def func(n,output_queue):
start = time.time()
print(n, time.time())
count=0
for i in range(10000000) :
output_queue.put(i)
count+= i
stop = time.time()
print(n, stop-start)
if __name__ == '__main__':
start = time.time()
output = Queue()
thread_list = []
for i in range(10):
th = Process(target=func, args=(i,output))
thread_list.append(th)
th.start()
for th_item in thread_list:
th_item.join()
print("主进程执行完毕!")
执行结果:只有启动的时间戳,没有结束后的时间差打印
1 1623144548.5340202
2 1623144548.54046
0 1623144548.541418
4 1623144548.554847
5 1623144548.5567539
3 1623144548.569429
6 1623144548.588167
7 1623144548.588607
8 1623144548.599915
9 1623144548.604539
个人因为需要用多进程,也遇到了上面的问题,网上也搜索了很多,其实都给出明确的解决方法,大多是给出了问题,没有解答
1.卡死原因分析: 通过多次实验得出的结果推测,不是多进程执行有bug,是我们没理解多进程下的大数据执行的生产消费模式,比如子进程里 queue put进去,而主进程没有去消费,那么join是不会等到结束的
2.解决方案:加入消费模式,在join前,把队列的内容消费掉
from multiprocessing import Queue,Process
def func(n,output_queue):
start = time.time()
print(n, time.time())
count=0
for i in range(10000) :
output_queue.put(i)
count+= i
stop = time.time()
print(n, stop-start)
if __name__ == '__main__':
start = time.time()
output = Queue()
thread_list = []
for i in range(10):
th = Process(target=func, args=(i,output))
thread_list.append(th)
th.start()
for th_item in thread_list:
while th_item.is_alive():
while False == output.empty():
output.get()
for th_item in thread_list:
th_item.join()
print("主进程执行完毕!")
执行结果:可以看到进程完成了最终的时间差打印
0 1623145645.839355
2 1623145645.840235
3 1623145645.8440099
1 1623145645.8445828
5 1623145645.8514628
6 1623145645.872386
4 1623145645.876878
7 1623145645.885157
8 1623145645.898742
9 1623145645.914007
3 0.8899681568145752
0 1.0251119136810303
2 1.0923209190368652
1 1.2704861164093018
5 1.3352081775665283
4 1.52469801902771
6 1.5615859031677246
7 1.6239848136901855
8 1.6524741649627686
9 1.6379320621490479
主进程执行完毕!
没有具体分析多进程内部代码,详细原因猜测,应该是queue的put 达到一个数量之后会锁住子进程,即时消费掉,才能保证子进程的持续执行
本文介绍了在Python多进程中使用Queue进行数据传递时可能出现的进程卡死问题。当Queue不断添加元素,可能导致进程无法正常结束。分析发现,问题在于子进程生产数据但主进程未及时消费,从而引发阻塞。解决方法是在调用join之前确保Queue内容被消费,以保持子进程的持续执行。实验结果显示,该方案能有效避免进程卡死,使程序正常运行并完成预期任务。
635

被折叠的 条评论
为什么被折叠?



