Python多进程使用Queue后卡死问题解决方案

本文介绍了在Python多进程中使用Queue进行数据传递时可能出现的进程卡死问题。当Queue不断添加元素,可能导致进程无法正常结束。分析发现,问题在于子进程生产数据但主进程未及时消费,从而引发阻塞。解决方法是在调用join之前确保Queue内容被消费,以保持子进程的持续执行。实验结果显示,该方案能有效避免进程卡死,使程序正常运行并完成预期任务。
部署运行你感兴趣的模型镜像

很多人在使用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 达到一个数量之后会锁住子进程,即时消费掉,才能保证子进程的持续执行

您可能感兴趣的与本文相关的镜像

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值