1. Queue模块简介
Python是一种解释性的语言,单线程程序的执行效率会受到一定的影响。在Python中,如果需要在不同线程间共享数据,需要使用Queue来进行数据交换。Queue模块是Python多线程编程中的重要组成部分,通过Queue模块,我们可以在多个线程间通信,共享数据。Queue类提供了常见的队列模型(如FIFO)等操作,自动完成线程同步和锁定等功能,开发者只需要在适当的地方插入put(),get()等关键代码即可。
2. Queue模块的主要方法
2.1 Queue类的构造方法
Queue类的构造函数默认创建一个长度为0的空队列,也可以创建一个具有初始长度的队列。具体使用方法见下方示例代码:
import queue
q = queue.Queue(maxsize=20)
这种方法创建的队列容量为20,最多只能放20个元素。
2.2 put()方法
put()方法用于队列的插入操作。在Queue队列中可以插入任何可迭代对象,包括字符串、列表等。如果当前队列已满则put()方法会阻塞线程,直到有空间可以插入元素。
import queue
q = queue.Queue(maxsize=4)
q.put(1)
q.put('John')
q.put({'Name': 'Bill', 'Age': 25})
q.put([1, 2, 3])
在上述代码片段中,q.put()顺序插入了4个对象到队列中,由于该队列最多只能容纳4个元素,因此最后一个put()方法调用时发生了阻塞。
2.3 get()方法
get()方法用于队列的取出操作。当Queue队列取出完所有元素时,get()方法会阻塞线程,直到队列中有新的元素可以取出。
import queue
q = queue.Queue(maxsize=4)
q.put(1)
q.put('John')
q.put({'Name': 'Bill', 'Age': 25})
q.put([1, 2, 3])
while not q.empty():
item = q.get()
print(item)
在上述代码片段中,首先向队列中插入4个元素。while循环随后循环取出队列中的元素,直到队列为空时退出循环。
2.4 qsize()方法
qsize()方法是Queue类自带的,用于获取队列的当前大小。虽然qsize()方法返回的值是近似值,但在多线程程序中可以做为一个较为可靠的参考值。
import queue
q = queue.Queue(maxsize=4)
q.put(1)
q.put('John')
q.put({'Name': 'Bill', 'Age': 25})
q.put([1, 2, 3])
print(q.qsize())
2.5 task_done()方法
task_done()方法通知队列任务已经完成。每一个从Queue队列中取出的元素,都应该在处理完毕后,调用这个方法以告知队列一个元素已经被处理。调用get()方法时,Queue会追踪每一个向队列插入而没有取出的元素,这些未取出的元素默认会阻塞其他的put()方法调用。为了防止这种情况的发生,Queue提供了一个task_done()方法,以告知Queue相关元素已经被消耗。
2.6 join()方法
join()方法等待队列元素全部被处理掉,再继续执行程序。需要注意的是,如果队列中任务没有处理完成或者还有任务在等待队列中,join()方法会一直阻塞线程。
下面是一个简单的队列例子:
import threading
import queue
import time
# 定义一个Queue类的队列
queueVar = queue.Queue(6)
class ProducerThread(threading.Thread):
def run(self):
# 将数字1到10放入queueVar队列
for i in range(1, 11):
time.sleep(1)
print('Inserting %d into the queue.' % i)
queueVar.put(i)
print('Producer has finished producing all the items.')
class ConsumerThread(threading.Thread):
def run(self):
while True:
# 接收从ProducerThread中传来的值
item = queueVar.get()
time.sleep(2)
print('Processing %d' % item)
# 表示已经从队列里面拿到了一个元素,等同于task_done()
queueVar.task_done()
if queueVar.qsize() == 0:
break
if __name__ == '__main__':
producerThread = ProducerThread()
consumerThread = ConsumerThread()
# 启动Producer线程
producerThread.start()
# 启动Consumer线程
consumerThread.start()
# 等待Producer结束
producerThread.join()
# 等待Consumer结束
queueVar.join()
print('Program is finished.')
执行结果如下:
Inserting 1 into the queue.
Inserting 2 into the queue.
Processing 1
Inserting 3 into the queue.
Inserting 4 into the queue.
Processing 2
Inserting 5 into the queue.
Inserting 6 into the queue.
Processing 3
Inserting 7 into the queue.
Inserting 8 into the queue.
Processing 4
Inserting 9 into the queue.
Inserting 10 into the queue.
Processing 5
Processing 6
Processing 7
Processing 8
Processing 9
Processing 10
Producer has finished producing all the items.
Program is finished.
3.总结
在Python多线程编程中,Queue模块是一种非常重要的组成部分。通过Queue模块,我们可以在不同线程间共享数据,并自动完成线程同步和锁定等功能。Queue类提供了常见的队列模型,开发者只需要在适当的位置插入put(),get()等关键代码即可。本文主要介绍了Queue模块的一些主要方法,包括构造函数、put()、get()、qsize()、task_done()和join()等方法。对于新手学习Queue模块以及Python多线程编程的开发者来说,可以参照本文提供的示例代码,更好地理解Queue模块的使用方式和多线程编程的特点。