Python多线程 Queue 模块常见用法

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模块的使用方式和多线程编程的特点。

后端开发标签