Python 使用同步队列
Python 使用同步队列
Python 中的Queue
模块实现了多生产者、多消费者队列。队列在多线程程序中,当不同的线程需要安全地交换信息时非常有用。同步队列的好处是,他们带有所有必需的锁机制,不再需要额外的锁。
在 Queue
模块中,有三种类型的队列:
- FIFO: 先进先出队列;
- LIFO: 后进先出队列;
- Priority Queue:优先级队列;在这个队列中,记录是被排序的,并且拥有最低值的记录被首先获取。
这些队列使用锁保护记录被互相竞争的线程访问。在下面的代码中,我们创建了一个 FIFO
队列,队列里存放着桩任务。为了处理队列中的任务,我们通过继承 Thread
类,创建了一个定制类,这是创建线程的另一种方式。
为了实线程现定制类,我们需要重写 init
和 run
方法。在 init
方法中,要求调用父类的 init
方法。run
方法是线程类的可执行部分。完整的代码示例如下:
from multiprocessing.pool import worker
from queue import Queue
from threading import Thread
from time import sleep
class MyWorker(Thread):
def __init__(self, name, queue):
Thread.__init__(self)
self.name = name
self.queue = queue
def run(self):
while True:
item = self.queue.get()
sleep(1)
try:
print("{}: {}".format(self.name, item))
finally:
self.queue.task_done()
# 填充队列
myqueue = Queue()
for i in range(10):
myqueue.put("任务 {}".format(i + 1))
# 创建线程
for i in range(5):
worker = MyWorker("线程 {}".format(i + 1), myqueue)
worker.daemon = True
worker.start()
myqueue.join()
以上代码的输出结果是(仅供参考):
线程 3: 任务 3
线程 4: 任务 4
线程 1: 任务 1
线程 5: 任务 5线程 2: 任务 2
线程 3: 任务 6
线程 2: 任务 9
线程 4: 任务 7
线程 1: 任务 8
线程 5: 任务 10
在线程中,每一个调用 get
方法从队列中获取一个任务后,就用调用 task_done
方法,来表明任务已经处理完毕。
非常需要注意的是,我们没有在线程上调用 join
方法,而是调用的 myqueue
的 join
方法。myqueue
的 join
方法阻塞了主线程在任务处理完之前退出。当使用一个队列保存被处理的数据时,这是一种被推荐的方法。
<完>