lock = threading.Lock()
def add():
global count
with lock:
count += 1
十个线程各对同一个全局变量加一千次,跑完打印出来是九千三百多,每次结果都不一样,代码里就一句 count += 1。这类现象通常不是突然出现的,往前翻半天日志能看到苗头。
追下去是这么回事:count += 1 拆成读取、相加、写回三步,线程在这三步之间被切走,两个线程读到同一个旧值,写回时互相覆盖,更新就这么丢了,计数自然偏小。
「线程共享计数」排查到最后往往是很小的一处差异,前面那些复杂猜测可以先放一放。同一份配置存在多处的,先确认改的是被加载的那一份。
新版本先放一台机器上跑一天再全量,问题一般在这段时间暴露。
处理上按这个顺序:共享计数用 Lock 把读取、相加、写回这三步包在一起,别分开写;整数计数直接用带锁的计数器或者队列来汇总;每个线程先算局部结果,最后统一合并减少争用。
确认没问题再收工,连续十轮跑下来结果都等于一万,不再出现少几百的情况,计数准确。
