Python多线程 Queue 模块常见用法

  

Python多线程 Queue 模块常见用法

多线程编程中,线程之间的通信是经常遇到的问题。Python中的Queue模块可以很好地解决这个问题。本文将详细讲解Queue模块的常用方法和使用场景。

基本用法

Queue模块提供了FIFO队列、LIFO队列,以及优先级队列三种数据结构。

import queue

# 创建一个FIFO队列
fifo_queue = queue.Queue()

# 创建一个LIFO队列
lifo_queue = queue.LifoQueue()

# 创建一个优先级队列,其中元组的第一个元素为优先级,数字越小,优先级越高
priority_queue = queue.PriorityQueue()

# 将元素放入队列中,队列支持多线程安全,因此可以多个线程同时调用put方法
fifo_queue.put('Python')
lifo_queue.put('Python')
priority_queue.put((1, 'Python'))

# 取出队列中的元素,如果队列为空,get方法会阻塞,直到有元素可以取出
print(fifo_queue.get())
print(lifo_queue.get())
print(priority_queue.get()[1])

运行结果为:

Python
Python
Python

线程间通信

在多线程编程中,常常需要将数据从一个线程传递到另一个线程。Queue模块提供了线程安全的队列,可以很好地解决这个问题。

import queue
import threading

def producer(q):
    for i in range(5):
        q.put(i)
        print('put', i)
    # put方法在队列已满时会阻塞,因此需要调用q.join()等待队列为空
    q.join()

def consumer(q):
    while True:
        data = q.get()
        print('get', data)
        q.task_done()

q = queue.Queue()
t1 = threading.Thread(target=producer, args=(q,))
t2 = threading.Thread(target=consumer, args=(q,))
t1.start()
t2.start()
t1.join()
t2.join()

在该示例中,producer函数向队列中放入数据,consumer函数从队列中取出数据并处理。在主线程中创建两个子线程,分别调用producerconsumer函数。在producer函数中,调用Queue的put方法向队列中放入数据,当队列已满时会阻塞。在consumer函数中,循环调用Queue的get方法取出队列中的元素,当队列为空时会阻塞,直到队列中有元素可以取出。队列的task_done方法可以通知队列,表示该元素已经取出并处理完毕。

运行结果为:

put 0
put 1
put 2
put 3
put 4
get 0
get 1
get 2
get 3
get 4

阻塞式队列

Queue模块提供了阻塞式队列,当队列已满或队列为空时,队列的putget方法会阻塞,直到队列中有元素可取或队列不再已满。以下是一个阻塞式队列的示例:

import queue
import threading
import time
import random

def producer(q):
    while True:
        data = random.randint(0, 10)
        q.put(data)
        print('put', data)
        time.sleep(1)

def consumer(q):
    while True:
        data = q.get()
        print('get', data)
        time.sleep(2)

q = queue.Queue(5) # 创建一个队列,最多可以存放5个元素
t1 = threading.Thread(target=producer, args=(q,))
t2 = threading.Thread(target=consumer, args=(q,))
t1.start()
t2.start()
t1.join()
t2.join()

在该示例中,producer函数无限循环地向队列中放入随机数值,在队列已满时阻塞。consumer函数无限循环地取出队列中的值,在队列为空时阻塞。在主线程中创建producerconsumer两个子线程,分别调用producerconsumer函数,最多只能存放5个元素。

运行结果为:

put 0
get 0
put 1
put 2
get 1
put 10
get 2
put 9
get 10
put 2
get 9
put 7
get 2
put 4
get 7
相关文章