问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

Python 队列queue与多线程组合(生产者+消费者模式)

发布网友 发布时间:2022-12-04 09:22

我来回答

1个回答

热心网友 时间:2024-05-21 14:55

在线程世界⾥,⽣产者就是⽣产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果⽣产者处理速度很快,⽽消费者处理速度很慢,那么⽣产者就必须等待消费者处理完,才能继续⽣产数据。同样的道理,如果消费者的处理能⼒⼤于⽣产者,那么消费者就必须等待⽣产者。为了解决这个问题于是引⼊了⽣产者和消费者模式。

⽣产者消费者模式是通过⼀个容器来解决⽣产者和消费者的强耦合问题。⽣产者和消费者彼此之间不直接通讯,⽽通过阻塞队列来进⾏通讯,所以⽣产者⽣产完数据之后不⽤等待消费者处理,直接扔给阻塞队列,消费者不找⽣产者要数据,⽽是直接从阻塞队列⾥取,阻塞队列就相当于⼀个缓冲区,平衡了⽣产者和消费者的处理能⼒。

比如,对于同时爬取多个网页的多线程爬虫,在某一时刻你可能无法保证他们在处理不同的网站,在某些时刻他们极有可能在处理相同的网站,这岂不浪费?为了解决这个问题,可以将不同网页的url放在queue中,然后多个线程来读取queue中的url进行解析处理,而queue只允许一次出一个,出一个少一个。相同网站上不同网页的url通常有某种规律,比如某个字段的数字加1,这种情况完全可以用这种模式,“生产者程序”负责根据规律把完整的url制作出来,再塞进queue里面(如果queue满了,则等待);“消费者程序(网页解析程序)”从queue的后面挨个取出url进行解析(如果queue里面是空的,则等待),即使是多线程也能保证每个线程得到的是不同的url。这个过程中,生产者和消费彼此互不干涉。

下面以实例说明如何将queue与多线程相结合形成所谓的“生产者+消费者”模式,同时解决多线程如何退出的问题(注意下例中是“一个生产者+多个消费者”的形式,多生产者+多消费者的模式可在此基础上进一步实现):

上述程序的过程如下图:

注意
(1)上述程序中生产者插入queue的时间间隔为0.1s,而消费者的取出时间间隔为2s,显然消费速度不如生产速度,一开始queue是空的,一段时间后queue就变满了,输出结果正说明了这一点。如果将两个时间调换,则结果相反,queue永远不会满,甚至只有1个值,因为只要进去就被消费了。
(2)消费者程序是通过“while”来推动不断执行的,何时结束?上例中通过在queue中增加None的形式告诉消费者,生产者已经结束了,消费者也可以结束了。但消费者有多个,到底由哪个消费者得到None?为解决这个问题,上例中在消费者中先判断当前取出的是不是None,如果是,则先在queue里插入一个None,然后再break当前这个消费者线程,最后的结果是所有的消费者线程都退出了,但queue中还剩下None没有被取出。因此在程序的后面增加了一个for循环来挨个把queue中的元素取出,否则最后的q.join()将永远阻塞,程序无法往下执行。
(3)程序中每一个q.get()后面都跟有一个q.task_done(),其作用是从queue中取出一个元素就给q.join()发送一个信息,否则q.join()将永远处于阻塞状态,直到所有queue元素都被取出。

多线程“生产者-消费者”模式一般性结构图

热心网友 时间:2024-05-21 14:55

在线程世界⾥,⽣产者就是⽣产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果⽣产者处理速度很快,⽽消费者处理速度很慢,那么⽣产者就必须等待消费者处理完,才能继续⽣产数据。同样的道理,如果消费者的处理能⼒⼤于⽣产者,那么消费者就必须等待⽣产者。为了解决这个问题于是引⼊了⽣产者和消费者模式。

⽣产者消费者模式是通过⼀个容器来解决⽣产者和消费者的强耦合问题。⽣产者和消费者彼此之间不直接通讯,⽽通过阻塞队列来进⾏通讯,所以⽣产者⽣产完数据之后不⽤等待消费者处理,直接扔给阻塞队列,消费者不找⽣产者要数据,⽽是直接从阻塞队列⾥取,阻塞队列就相当于⼀个缓冲区,平衡了⽣产者和消费者的处理能⼒。

比如,对于同时爬取多个网页的多线程爬虫,在某一时刻你可能无法保证他们在处理不同的网站,在某些时刻他们极有可能在处理相同的网站,这岂不浪费?为了解决这个问题,可以将不同网页的url放在queue中,然后多个线程来读取queue中的url进行解析处理,而queue只允许一次出一个,出一个少一个。相同网站上不同网页的url通常有某种规律,比如某个字段的数字加1,这种情况完全可以用这种模式,“生产者程序”负责根据规律把完整的url制作出来,再塞进queue里面(如果queue满了,则等待);“消费者程序(网页解析程序)”从queue的后面挨个取出url进行解析(如果queue里面是空的,则等待),即使是多线程也能保证每个线程得到的是不同的url。这个过程中,生产者和消费彼此互不干涉。

下面以实例说明如何将queue与多线程相结合形成所谓的“生产者+消费者”模式,同时解决多线程如何退出的问题(注意下例中是“一个生产者+多个消费者”的形式,多生产者+多消费者的模式可在此基础上进一步实现):

上述程序的过程如下图:

注意
(1)上述程序中生产者插入queue的时间间隔为0.1s,而消费者的取出时间间隔为2s,显然消费速度不如生产速度,一开始queue是空的,一段时间后queue就变满了,输出结果正说明了这一点。如果将两个时间调换,则结果相反,queue永远不会满,甚至只有1个值,因为只要进去就被消费了。
(2)消费者程序是通过“while”来推动不断执行的,何时结束?上例中通过在queue中增加None的形式告诉消费者,生产者已经结束了,消费者也可以结束了。但消费者有多个,到底由哪个消费者得到None?为解决这个问题,上例中在消费者中先判断当前取出的是不是None,如果是,则先在queue里插入一个None,然后再break当前这个消费者线程,最后的结果是所有的消费者线程都退出了,但queue中还剩下None没有被取出。因此在程序的后面增加了一个for循环来挨个把queue中的元素取出,否则最后的q.join()将永远阻塞,程序无法往下执行。
(3)程序中每一个q.get()后面都跟有一个q.task_done(),其作用是从queue中取出一个元素就给q.join()发送一个信息,否则q.join()将永远处于阻塞状态,直到所有queue元素都被取出。

多线程“生产者-消费者”模式一般性结构图

热心网友 时间:2024-05-21 14:55

在线程世界⾥,⽣产者就是⽣产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果⽣产者处理速度很快,⽽消费者处理速度很慢,那么⽣产者就必须等待消费者处理完,才能继续⽣产数据。同样的道理,如果消费者的处理能⼒⼤于⽣产者,那么消费者就必须等待⽣产者。为了解决这个问题于是引⼊了⽣产者和消费者模式。

⽣产者消费者模式是通过⼀个容器来解决⽣产者和消费者的强耦合问题。⽣产者和消费者彼此之间不直接通讯,⽽通过阻塞队列来进⾏通讯,所以⽣产者⽣产完数据之后不⽤等待消费者处理,直接扔给阻塞队列,消费者不找⽣产者要数据,⽽是直接从阻塞队列⾥取,阻塞队列就相当于⼀个缓冲区,平衡了⽣产者和消费者的处理能⼒。

比如,对于同时爬取多个网页的多线程爬虫,在某一时刻你可能无法保证他们在处理不同的网站,在某些时刻他们极有可能在处理相同的网站,这岂不浪费?为了解决这个问题,可以将不同网页的url放在queue中,然后多个线程来读取queue中的url进行解析处理,而queue只允许一次出一个,出一个少一个。相同网站上不同网页的url通常有某种规律,比如某个字段的数字加1,这种情况完全可以用这种模式,“生产者程序”负责根据规律把完整的url制作出来,再塞进queue里面(如果queue满了,则等待);“消费者程序(网页解析程序)”从queue的后面挨个取出url进行解析(如果queue里面是空的,则等待),即使是多线程也能保证每个线程得到的是不同的url。这个过程中,生产者和消费彼此互不干涉。

下面以实例说明如何将queue与多线程相结合形成所谓的“生产者+消费者”模式,同时解决多线程如何退出的问题(注意下例中是“一个生产者+多个消费者”的形式,多生产者+多消费者的模式可在此基础上进一步实现):

上述程序的过程如下图:

注意
(1)上述程序中生产者插入queue的时间间隔为0.1s,而消费者的取出时间间隔为2s,显然消费速度不如生产速度,一开始queue是空的,一段时间后queue就变满了,输出结果正说明了这一点。如果将两个时间调换,则结果相反,queue永远不会满,甚至只有1个值,因为只要进去就被消费了。
(2)消费者程序是通过“while”来推动不断执行的,何时结束?上例中通过在queue中增加None的形式告诉消费者,生产者已经结束了,消费者也可以结束了。但消费者有多个,到底由哪个消费者得到None?为解决这个问题,上例中在消费者中先判断当前取出的是不是None,如果是,则先在queue里插入一个None,然后再break当前这个消费者线程,最后的结果是所有的消费者线程都退出了,但queue中还剩下None没有被取出。因此在程序的后面增加了一个for循环来挨个把queue中的元素取出,否则最后的q.join()将永远阻塞,程序无法往下执行。
(3)程序中每一个q.get()后面都跟有一个q.task_done(),其作用是从queue中取出一个元素就给q.join()发送一个信息,否则q.join()将永远处于阻塞状态,直到所有queue元素都被取出。

多线程“生产者-消费者”模式一般性结构图

热心网友 时间:2024-05-21 14:55

在线程世界⾥,⽣产者就是⽣产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果⽣产者处理速度很快,⽽消费者处理速度很慢,那么⽣产者就必须等待消费者处理完,才能继续⽣产数据。同样的道理,如果消费者的处理能⼒⼤于⽣产者,那么消费者就必须等待⽣产者。为了解决这个问题于是引⼊了⽣产者和消费者模式。

⽣产者消费者模式是通过⼀个容器来解决⽣产者和消费者的强耦合问题。⽣产者和消费者彼此之间不直接通讯,⽽通过阻塞队列来进⾏通讯,所以⽣产者⽣产完数据之后不⽤等待消费者处理,直接扔给阻塞队列,消费者不找⽣产者要数据,⽽是直接从阻塞队列⾥取,阻塞队列就相当于⼀个缓冲区,平衡了⽣产者和消费者的处理能⼒。

比如,对于同时爬取多个网页的多线程爬虫,在某一时刻你可能无法保证他们在处理不同的网站,在某些时刻他们极有可能在处理相同的网站,这岂不浪费?为了解决这个问题,可以将不同网页的url放在queue中,然后多个线程来读取queue中的url进行解析处理,而queue只允许一次出一个,出一个少一个。相同网站上不同网页的url通常有某种规律,比如某个字段的数字加1,这种情况完全可以用这种模式,“生产者程序”负责根据规律把完整的url制作出来,再塞进queue里面(如果queue满了,则等待);“消费者程序(网页解析程序)”从queue的后面挨个取出url进行解析(如果queue里面是空的,则等待),即使是多线程也能保证每个线程得到的是不同的url。这个过程中,生产者和消费彼此互不干涉。

下面以实例说明如何将queue与多线程相结合形成所谓的“生产者+消费者”模式,同时解决多线程如何退出的问题(注意下例中是“一个生产者+多个消费者”的形式,多生产者+多消费者的模式可在此基础上进一步实现):

上述程序的过程如下图:

注意
(1)上述程序中生产者插入queue的时间间隔为0.1s,而消费者的取出时间间隔为2s,显然消费速度不如生产速度,一开始queue是空的,一段时间后queue就变满了,输出结果正说明了这一点。如果将两个时间调换,则结果相反,queue永远不会满,甚至只有1个值,因为只要进去就被消费了。
(2)消费者程序是通过“while”来推动不断执行的,何时结束?上例中通过在queue中增加None的形式告诉消费者,生产者已经结束了,消费者也可以结束了。但消费者有多个,到底由哪个消费者得到None?为解决这个问题,上例中在消费者中先判断当前取出的是不是None,如果是,则先在queue里插入一个None,然后再break当前这个消费者线程,最后的结果是所有的消费者线程都退出了,但queue中还剩下None没有被取出。因此在程序的后面增加了一个for循环来挨个把queue中的元素取出,否则最后的q.join()将永远阻塞,程序无法往下执行。
(3)程序中每一个q.get()后面都跟有一个q.task_done(),其作用是从queue中取出一个元素就给q.join()发送一个信息,否则q.join()将永远处于阻塞状态,直到所有queue元素都被取出。

多线程“生产者-消费者”模式一般性结构图

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
build腰带迷失漂流瓶几元 BANDAI万代假面骑士Build 飞电01驱动器-适用对象 BANDAI 万代 假面骑士Build 飞电01驱动器-详细介绍 纸胶带能做什么手工 黑死病是哪个时期 黑死病和伽利略谁的时代更早 双十二有购物津贴吗 双12购物津贴领取方法和使用规则 双十二满减是多少?满减有什么规则? 双十二满减规则是什么?详细内容介绍 双12淘宝如何满减?规则是什么? 语音识别原理 五分钟就能弄懂 Mac 音乐文件格式转换,转换mp3 纯电动汽车动力电池获取能量的方式有 请问纯电动汽车用什么电池 纯电动车运行时,动力电池电能主要去向及作用? 为什么志高空调总是比其他同配置的空调便宜 翡翠有小凹坑怎么回事 得道多助失道寡助译文简短 椰子树怎么画简单又漂亮图片 为什么苹果6S手机电脑不能同时登QQ 科技幻想画手抄报大全 十几减9有几种计算方法 具体名称和方法 青海邮政10月快递停运了吗 邮政快递到地方了没有疫情他说有疫情快递很地放几天是怎么回事?_百度... 山南贡嘎县邮政速递物流外包人员发生了什么? 为什么邮政快递会停在一个地方四天了? 帕萨特跟奥迪a6哪个底盘高些 君威和帕萨特哪个底盘高 帕萨特底盘最低高度 你了解多少 帕萨特和思域哪个底盘高 python3多线程通信方式,主要理解队列的join()和task_done()方法... 教资及格分数怎么算 机场地铁招保洁员是不是骗人上海? 中秋为什么要博饼 中秋博饼介绍 能问下,景德镇一中的武智理老师,现在还教书吗?还是已经坐办公室了_百... 景德镇市第一中学的办学条件 Polo的发动机型号 大众宝来dmb是什么发动机 excel 打开时会连接其他路径的文件,请问怎么取消。不是超链接。 建行聚合码丢了怎么打印 好看的穿越抗战小说 测绘工程技术专业是文科还是理科 就业方向有哪些 女童在幼儿园玩滑梯摔倒身亡,家属是怎么说的? 安安全全滑滑梯幼儿园社会教案 河北省2022年护理本科刚升入大专的学生可以报名吗 拖把杆中间的卡扣怎么拆卸 两个怎么同时登录 怎么才能在一台手机上同时登录两个呢? 关于食品安全的手抄报内容和口号大全 微信如何同时使用两个呢?