本文首发自「慕课网」,想了解更多IT干货内容,程序员圈内热闻,欢迎关注!
作者| 慕课网精英讲师 朱广蔚
生产者和消费者问题是线程模型中的经典问题:
Python 的内置模块 queue 提供了对生产者和消费者模型的支持,模块 queue 定义了类 Queue,类 Queue 表示一个被生产者和消费者共享的队列,类 Queue 提供如下常用方法:
方法 |
功能 |
get() |
从队列中取走数据,如果队列为空,则阻塞 |
put(item) |
向队列中放置数据,如果队列为慢,则阻塞 |
join() |
如果队列不为空,则等待队列变为空 |
task_done() |
消费者从队列中取走一项数据,当队列变为空时,唤醒调用 join() 的线程 |
创建生产者线程和消费者线程,使用一个共享队列连接这两个线程,代码如下:
import threading
import queue
q = queue.Queue()
代码块1234
def produce():
for item in ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']:
q.put(item)
print('produce %s' % item)
代码块1234
def consume():
for i in range(8):
item = q.get()
print(' consume %s' % item)
代码块1234
producer = threading.Thread(target=produce, args=())
consumer = threading.Thread(target=consume, args=())
producer.start()
consumer.start()
producer.join()
consumer.join()
代码块123456
运行程序,输出结果如下:
produce a
produce b
consume a
produce c
consume b
consume c
produce d
consume d
produce e
consume e
produce f
consume f
produce g
consume g
produce h
consume h
代码块12345678910111213141516
创建生产者、计算者、消费者线程:
import threading
import queue
q0 = queue.Queue()
q1 = queue.Queue()
代码块12345
def produce():
for item in ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']:
q0.put(item)
print('produce %s' % item)
代码块1234
def compute():
for i in range(8):
item = q0.get()
item = item.upper()
q1.put(item)
代码块12345
def consume():
for i in range(8):
item = q1.get()
print(' consume %s' % item)
代码块1234
producer = threading.Thread(target=produce, args=())
computer = threading.Thread(target=compute, args=())
consumer = threading.Thread(target=consume, args=())
producer.start()
computer.start()
consumer.start()
producer.join()
computer.join()
consumer.join()
代码块12345678910
运行程序,输出结果如下:
produce a
produce b
produce c
consume A
produce d
produce e
consume B
produce f
consume C
produce g
consume D
produce h
consume E
consume F
consume G
consume H
代码块12345678910111213141516
在生产者、消费者模型中,可能会存在两者推进速度不匹配的问题:生产者生产数据的速度较快,但是,消费者取走数据的速度较慢。
可以使用 queue 的 task_done() 方法和 join() 方法同步生产者与消费者的推进速度:
import threading
import queue
q = queue.Queue()
代码块1234
def produce():
for item in ['A', 'B', 'C', 'D']:
q.put(item)
print('produce %s' % item)
q.join()
print('------------ q is empty')
for item in ['E', 'F', 'G', 'H']:
q.put(item)
print('produce %s' % item)
q.join()
print('------------ q is empty')
代码块123456789101112
def consume():
for i in range(8):
item = q.get()
print(' consume %s' % item)
q.task_done()
代码块12345
producer = threading.Thread(target=produce, args=())
consumer = threading.Thread(target=consume, args=())
producer.start()
consumer.start()
代码块1234
运行程序,输出结果如下:
produce A
produce B
consume A
consume B
produce C
consume C
produce D
consume D
------------ q is empty
produce E
consume E
produce F
consume F
produce G
produce H
consume G
consume H
------------ q is empty
代码块123456789101112131415161718
欢迎关注「慕课网」,发现更多IT圈优质内容,分享干货知识,帮助你成为更好的程序员!