queue实现计数的核心是安全传递并汇总任务结果,而非直接计数;它通过线程/进程安全的put/get天然避免竞态条件,比手动管理全局变量+锁更可靠、易用。

在初级并发练习中,用 Queue 实现计数,核心不是让队列“直接计数”,而是利用它安全地传递和汇总任务结果——尤其适合多线程/多进程环境下避免竞态条件。
为什么不用全局变量+锁,而选 Queue?
Queue 是线程/进程安全的,内部已封装锁机制。初学者容易误用全局变量(如 count = 0)配合 threading.Lock,但稍不注意就会漏加锁、死锁或忘记释放。而 Queue.put() 和 Queue.get() 天然串行化访问,更直观、容错性高。
典型结构:生产者-消费者模式计数
把“要计数的东西”(比如一批数字、文件行、请求响应)分发给多个工作线程处理,每个线程处理完,把局部结果(如处理了几个、是否成功)放进队列;主线程最后统一取出并累加。
- 创建一个
queue.Queue()(线程)或multiprocessing.Queue()(进程) - 启动多个 worker 线程,每个从任务列表取数据 → 处理 →
q.put(1)或q.put(result) - 主线程调用
q.get()多次(或用q.empty()配合等待),把所有结果相加
一个小而完整的线程示例(统计 100 个数里偶数个数)
不追求性能,重在逻辑清晰:
import threading
import queue
import time
<p>def worker(nums, q):
count_even = 0
for n in nums:
if n % 2 == 0:
count_even += 1
q.put(count_even) # 安全提交局部结果</p><p>q = queue.Queue()
data = list(range(1, 101))
chunk_size = 25
threads = []</p><h1>分4组,每组25个数</h1><p>for i in range(0, len(data), chunk_size):
t = threading.Thread(target=worker, args=(data[i:i+chunk_size], q))
threads.append(t)
t.start()</p><p>for t in threads:
t.join()</p><p>total_even = 0
while not q.empty():
total_even += q.get()</p><p>print("偶数总数:", total_even) # 输出 50
</p>关键提醒(初学者易错点)
- 别在 worker 里直接操作共享变量(如
global count),哪怕加了锁——这违背用 Queue 的初衷 - 用
q.empty()判断队列为空不可靠(可能刚判空就进新数据),更稳妥的是按预期数量get(),或用q.task_done()+q.join()配合 - 若用
multiprocessing,注意函数和数据需可序列化(不能传 lambda、嵌套函数、带未定义属性的对象) - Queue 不是万能计数器:它适合“离散结果聚合”,不适合实时高频递增(如每毫秒+1)。那种场景该用
threading.AtomicInteger(Python 没原生,可用threading.local或concurrent.futures管理)











