目录
1. 什么是生产者消费者模型
- 生产者 : 程序中负责产生数据的一方
- 消费者 : 程序中负责处理数据的一方
2. 为什么引入生产者消费者模型
在并发编程中, 生产者消费者模式通过一个容器来解决生产者和消费者之间的强耦合性, 两者之间不再是直接通信, 而是通过堵塞队列来进行通信, 生产者(生产速度快)不必再等待消费者是否处理完数据, 消费者直接从队列中取, 该队列就相当于一个缓冲区, 平衡了生产者和消费者的工作能力, 从而提高了程序整体的数据处理速度
3. 如何实现
通过队列 : 生产者------>队列------->消费者
4. 示例
producer_consumer_spider.py
import queue
import random
import threading
import time
import blog_spider
def do_craw(url_queue: queue.Queue, html_queue: queue.Queue):
while True:
url = url_queue.get()
html = blog_spider.craw(url)
html_queue.put(html)
print(threading.current_thread().name, f"craw {url}", "url_queue.size=", url_queue.qsize())
time.sleep(random.randint(1, 2))
def do_parse(html_queue: queue.Queue, fout):
while True:
html = html_queue.get()
results = blog_spider.parse(html)
for result in results:
fout.write(str(result) + '\n')
print(threading.current_thread().name, f"results.size", len(results), "html_queue.size=", html_queue.qsize())
time.sleep(random.randint(1, 2))
if __name__ == '__main__':
url_queue = queue.Queue()
html_queue = queue.Queue()
for url in blog_spider.urls:
url_queue.put(url)
for idx in range(3):
t = threading.Thread(target=do_craw, args=(url_queue, html_queue), name=f"craw{idx}")
t.start()
fout = open("02.data.txt", "w", 1024, 'utf-8')
for idx in range(2):
t = threading.Thread(target=do_parse, args=(html_queue, fout), name=f"parse{idx}")
t.start()
参考资料: