【Python】queue模块Queue对象-CSDN博客

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

Python中的queue模块是一个同步队列类实现了多生产者、多消费者队列适用于在多线程之间安全地传递消息或其他数据。Queue提供了所有必需的锁定语义。

queue模块有三种类型的队列只是队列中元素的提取顺序不同先进先出FIFO队列后进先出LIFO队列优先级队列涉及heapq模块。

其中Queue对象 (Queue, LifoQueue, 或者 PriorityQueue) 。

Queue先进先出FIFO。LifoQueue后进先出LIFO。PriorityQueue优先级队列。

from queue import Queue, LifoQueue, PriorityQueue

[x for x in dir(Queue) if not x.startswith('_')]
# 结果
['empty', 'full', 'get', 'get_nowait', 'join', 'put', 'put_nowait', 'qsize', 'task_done']

[x for x in dir(LifoQueue) if not x.startswith('_')]
# 结果
['empty', 'full', 'get', 'get_nowait', 'join', 'put', 'put_nowait', 'qsize', 'task_done']

[x for x in dir(PriorityQueue) if not x.startswith('_')]
# 结果
['empty', 'full', 'get', 'get_nowait', 'join', 'put', 'put_nowait', 'qsize', 'task_done']

Queue对象的方法以queue.Queue()为例

q = queue.Queue()实例化Queue对象。即线程安全队列此队列先进先出队尾进队头出。可限制队列大小超过最大限制则会阻塞若未提供最大限制默认maxsize=0则表示未限制队列大小。

q.qsize()返回队列的大致大小即队列中有多少元素。多线程时其它线程可能正在更新队列因此只能是队列的大致大小。

q.empty()判断队列是否为空。

q.full()判断队列是否是满的。

q.put(...)将元素添加到队列的队尾中。

q.get()从队列的队头移除一个元素并返回该元素。即从队列获取元素并从队列移除。

q.task_done()表示之前队列中排队的任务已被执行完毕。即get()获取任务后调用task_done()则告诉队列任务已处理完。

q.join()阻塞到队列中所有元素都被取出且被执行完毕。即队列被处理空主线程才继续往下执行。

举例

import threading
import queue

def worker():
    while True:
        # 获取元素从队头移除元素并返回该元素
        item = q.get()
        # 打印当前的线程名称和获取的元素
        print(f'Starting {threading.current_thread().name} : item = {item}\n')
        print(f'Finished {threading.current_thread().name} : item = {item}\n')
        # 告诉队列当前的任务已处理完毕
        q.task_done()
        print(f'队列是否为满{q.full()} 队列大致大小{q.qsize()}。\n')

# 线程安全队列此处未限制队列大小
q = queue.Queue()
print(f'队列是否为空{q.empty()}\n') 

# 创建4个线程并发执行
for i in range(4):
    t = threading.Thread(target=worker, name=f'threading{i}')
    t.start()

# 共6个线程当前主线程4个创建的线程1个socketThread
print(f'共有线程{threading.active_count()}个\n {threading.enumerate()}\n')

# 往队尾放入8个元素0-7
for item in range(8):
    q.put(item)
    if item == 7: print(f'队列是否为满{q.full()} 队列大致大小{q.qsize()}。\n')

# 等待队列中所有元素都处理完毕主线程继续往下执行
q.join()

print('All work completed')

结果

补充多生产者—多消费者【同步、互斥问题】

固定大小的缓冲区多个生产者往缓冲区写数据多个消费者从缓冲区读数据。

生产者先写数据然后消费者才能读数据。【同步问题】

缓冲区不满生产者才能写数据。【同步问题】

缓冲区互斥访问。【互斥问题】

结合pythonq = queue.Queue()线程安全队列表示缓冲区。

                      q.put(...)生产者往缓冲区写数据。

                      q.get()消费者从缓冲区读数据。

                      Queue对象 已具备所有必需的“锁”会为调用者处理锁定。

参考queue --- 一个同步的队列类 — Python 3.12.0 文档

 

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: python