为何保留time.sleep(0.5)时Python多进程程序输出非1,2,3?
为什么你的多进程锁没生效?踩中了内存隔离的坑!
你这个问题我之前也碰到过,核心原因其实是Python多进程之间的内存是完全隔离的——每个子进程启动时都会复制主进程的全部内存数据作为自己的初始状态,它们的全局变量是各自独立的副本,根本不共享!
为啥加了锁还是输出2,2,2?
你的icout是个普通全局变量,三个子进程刚启动时,各自的icout初始值都是主进程里的1。虽然你用Lock保证了同一时间只有一个进程执行临界区代码,但每个进程修改的都是自己那份icout:
- 进程A拿到锁,把自己的
icout从1改成2,打印2 - 进程B拿到锁,同样把自己的
icout从1改成2,打印2 - 进程C同理,还是输出2
加上time.sleep(0.5)后,三个进程都有足够时间完成初始化并排队等锁,所以最终就是三个2。
那去掉sleep为啥会输出1,2,3?
这纯属进程调度的巧合!没有sleep时,进程执行速度极快,第一个进程可能在另外两个进程还没完全初始化好的时候就完成了修改和打印,然后第二个、第三个进程依次跟上,刚好呈现出递增的结果。但本质上每个进程还是在改自己的icout副本,你多运行几次,大概率会得到不同的输出,这个结果完全不可靠。
怎么正确实现共享计数器?
要让多进程共享一个计数器,得用Python专门提供的共享内存工具,比如multiprocessing.Value或者multiprocessing.Manager。给你改好了代码,用Value实现稳定的递增:
import multiprocessing import time def send_request(data): lock.acquire() time.sleep(0.5) # 注意这里用.value访问共享变量 icout.value += 1 print(icout.value) lock.release() def init(l, counter): global lock, icout lock = l icout = counter if __name__ == '__main__': data_list = ['data1', 'data2', 'data3'] lock = multiprocessing.Lock() # 创建共享整数变量,初始值设为1(如果要输出1,2,3就设为0) icout = multiprocessing.Value('i', 1) pool = multiprocessing.Pool(3, initializer=init, initargs=(lock, icout)) pool.map(send_request, data_list) pool.close() pool.join()
关键点解释:
multiprocessing.Value('i', 1)创建了一个跨进程共享的整数变量,'i'代表整数类型- 所有子进程修改的都是这个共享变量,所以数值会真正递增
- 锁还是必须的,用来防止多个进程同时修改计数器导致的竞态问题(比如两个进程同时读1,然后都改成2,就又出问题了)
内容的提问来源于stack exchange,提问作者inaMinute
相关产品推荐
相关产品推荐

