queue本身线程安全,无需文件流或sleep同步;应直接用put/get操作计数,避免竞态和i/o干扰,推荐用logging观察执行过程。

在初级高并发练习中,用 Queue 实现线程安全计数,根本不需要“结合文件流的 sleep 方法”来同步——这种组合不仅无效,反而会引入严重问题。
Queue 本身已线程安全,无需额外加锁
queue.Queue 是 Python 标准库中专为多线程设计的线程安全队列。它的 put()、get()、qsize()(注意:不推荐依赖)等操作内部已用锁保护。你只需把计数行为封装成“放/取任务”,就能天然避免竞态:
- 启动多个线程,每个线程执行
q.put(1)模拟一次计数 - 主线程用
q.get()累加,或用q.qsize()读当前待处理数量(仅作观察,不用于逻辑判断) - 完全不用手动加
threading.Lock,更不需要文件流或sleep
文件流 + sleep 不是同步手段,而是干扰源
用文件写入模拟“共享变量”再配合 time.sleep() 等待,本质是忙等待+I/O阻塞,会导致:
- 文件读写本身非原子操作,多个线程同时写同一文件极易损坏数据
-
sleep无法保证时机,可能睡过头或没睡够,无法解决竞态 - I/O 是性能瓶颈,在高并发练习中会掩盖真实线程协作问题,偏离学习目标
一个干净可运行的初级示例
以下代码用 Queue 安全统计 100 个线程各贡献 1 次的总数:
<font size="2"><pre class="brush:php;toolbar:false;">import queue
import threading
import time
<p>q = queue.Queue()</p><p>def worker():
q.put(1) # 安全入队,无竞争</p><h1>启动 100 个线程</h1><p>threads = []
for _ in range(100):
t = threading.Thread(target=worker)
t.start()
threads.append(t)</p><h1>等所有线程完成</h1><p>for t in threads:
t.join()</p><h1>安全获取总数(逐个取,不依赖 qsize)</h1><p>total = 0
while not q.empty():
total += q.get()</p><p>print("总计数:", total) # 输出 100
</p>
如果真想观察执行过程,用 logging 而非 sleep
初学时想“看清楚每一步”,推荐用 logging 打印带线程名的日志,而不是靠 sleep 控制节奏:
- 加
logging.basicConfig(level=logging.INFO, format='%(threadName)s: %(message)s') - 在
worker中写logging.info("已计数") - 日志输出顺序反映实际调度,比盲目 sleep 更有教学意义











