
Python 的 queue 模块本身是线程安全的,无需额外加锁即可在多线程环境中安全使用。它的并发安全性由底层的 threading.Lock 保障,所有关键操作(如 put()、get()、qsize() 等)都已内置锁机制。
queue模块的线程安全原理
该模块内部为每个队列实例维护一个 threading.Lock 实例,在执行以下操作时自动加锁:
-
put(item, block=True, timeout=None):入队时锁定,防止多个线程同时修改内部列表 -
get(block=True, timeout=None):出队时锁定,并在空队列且block=True时配合Condition等待 -
task_done()和join():用于任务协同,同样受同一把锁保护
注意:qsize()、empty()、full() 在部分平台(如 macOS 或某些 Python 实现)可能不完全可靠,因为它们返回的是瞬时状态,不参与阻塞逻辑,仅作参考用。
典型多线程队列使用模式
标准用法是“生产者–消费者”模型,配合 threading.Thread 使用:
立即学习“Python免费学习笔记(深入)”;
- 创建一个
queue.Queue(maxsize=0)(默认无上限)或指定大小限制 - 启动多个生产者线程调用
put(),可选timeout避免无限阻塞 - 启动多个消费者线程调用
get(),处理完后必须调用task_done() - 主线程中用
join()等待所有任务完成
示例关键片段:
q = queue.Queue()def producer():
q.put(item)
def consumer():
item = q.get()
# 处理 item
q.task_done()
# 启动线程后,主线程调用 q.join() 等待全部 task_done
不适用于多进程场景
queue.Queue 仅保证线程安全,**不支持多进程间共享**。跨进程通信需改用 multiprocessing.Queue,它基于管道(pipe)和锁实现进程安全,接口类似但底层机制不同。
- 不要在
multiprocessing.Process中直接传入主线程创建的queue.Queue实例 - 若需进程+线程混合并发,各层应使用对应模块:
threading配queue.Queue,multiprocessing配multiprocessing.Queue或multiprocessing.Manager().Queue()
避免常见误用
- 不要手动对
queue.Queue实例加锁——会引发死锁或破坏原有同步逻辑 - 避免在循环中频繁调用
empty()判断后立即get(),因状态可能变化;应捕获queue.Empty异常更可靠 - 使用
put_nowait()或get_nowait()时需主动处理queue.Full/queue.Empty异常 - 确保每个
get()都对应一次task_done(),否则join()将永远等待










