Queue队列中join()与task_done()的关系是什么


这篇文章主要介绍了Queue队列中join()与task_done()的关系是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Queue队列中join()与task_done()的关系是什么文章都会有所收获,下面我们一起来看看吧。在网上大多关于join()与task_done()的结束原话是这样的:Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号Queue.join() 实际上意味着等到队列为空,再执行别的操作如果线程里每从队列里取一次,但没有执行task_done(),则join无法判断队列到底有没有结束,在最后执行个join()是等不到结果的,会一直挂起。可以理解为,每task_done一次 就从队列里删掉一个元素,这样在最后join的时候根据队列长度是否为零来判断队列是否结束,从而执行主线程。下面看个自己写的例子: 下面这个例子,会在join()的地方无限挂起,因为join在等队列清空,但是由于没有task_done,它认为队列还没有清空,还在一直等。如果把self.queue.task_done() 注释去掉,就会顺利执行完主程序。这就是“ Queue.task_done()函数向任务已经完成的队列发送一个信号”这句话的意义,能够让join()函数能判断出队列还剩多少,是否清空了。而事实上我们看下queue的源码可以看出确实是执行一次未完成队列减一:上面的演示代码是快速生产-慢速消费的场景,我们可以直接用task_done()与join()配合,来让empty()判断出队列是否已经结束。当然,queue我们可以正确判断是否已经清空,但是线程里的get队列是不知道,如果没有东西告诉它,队列空了,因此get还会继续阻塞,那么我们就需要在get程序中加一个判断,如果empty()成立,break退出循环,否则get()还是会一直阻塞。但是如果生产者速度与消费者速度相当,或者生产速度小于消费速度,则靠task_done()来实现队列减一则不靠谱,队列会时常处于供不应求的状态,常为empty,所以用empty来判断则不靠谱。那么这种情况会导致 join可以判断出队列结束了,但是线程里不能依靠empty()来判断线程是否可以结束。我们可以在消费队列的每个线程最后塞入一个特定的“标记”,在消费的时候判断,如果get到了这么一个“标记”,则可以判定队列结束了,因为生产队列都结束了,也不会再新增了。代码如下:put队列完成的时候千万不能用task_done(),否则会报错:因为该方法仅仅表示get成功后,执行的一个标记。关于“Queue队列中join()与task_done()的关系是什么”这篇文章的内容就介绍到这免费云主机域名里,感谢各位的阅读!相信大家对“Queue队列中join()与task_done()的关系是什么”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注百云主机行业资讯频道。

相关推荐: mysql的.ibd文件过大如何处理

这篇文章主要介绍了mysql的.ibd文件过大如何处理的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇mysql的.ibd文件过大如何处理文章都会有所收获,下面我们一起来看看吧。一条zabbix微信的磁盘告警打破了往常的宁静收到告警…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

(0)
打赏 微信扫一扫 微信扫一扫
上一篇 05/14 19:22
下一篇 05/14 19:22

相关推荐