Python中在一个函数修改全局变量,另一个函数检测的问题
问题根源:多进程的内存隔离
你遇到的问题核心在于multiprocessing的进程间内存隔离机制——当你使用Pool创建子进程时,每个子进程都会复制一份主进程的内存空间(包括全局变量n),也就是说,slowf和checkn操作的根本不是同一个列表对象!你打印的id(n)也能证明这一点:主进程、slowf子进程、checkn子进程里的n内存地址完全不同。
所以即使slowf往自己的副本里添加了元素,checkn看到的还是自己那份空列表,自然永远输出"F"。
解决方案:使用进程间共享数据结构
要让多个进程共享同一个变量,你需要用Pythonmultiprocessing模块提供的共享内存对象或者进程间通信机制,这里推荐两种简单可行的方法:
方法1:用multiprocessing.Manager创建可共享列表
Manager会创建一个独立的服务进程,用来管理共享数据,其他进程通过代理访问这个数据,这样就能保证所有进程操作的是同一个对象。修改后的代码如下:
import time from multiprocessing import Pool, Manager def slowf(n): time.sleep(5) n.append(1) print('slowf---', n, id(n)) def checkn(n): while 1: if n: print('checkn', n, id(n), "T") break else: print('checkn', n, id(n), "F") time.sleep(1) def main(): with Manager() as manager: n = manager.list() # 创建可共享的列表 print('main', id(n)) p = Pool() p.apply_async(slowf, args=(n,)) p.apply_async(checkn, args=(n,)) p.close() p.join() if __name__ == '__main__': main()
这里注意几点:
- 不再依赖全局变量,而是把共享列表作为参数传递给子进程函数
manager.list()创建的是一个代理对象,所有进程对它的操作都会同步到服务进程中的真实列表
方法2:用multiprocessing.Queue实现进程间通信
如果你的需求只是检测状态变化,用队列传递信号也是个好选择。slowf完成任务后往队列里放一个元素,checkn监听队列即可:
import time from multiprocessing import Pool, Queue def slowf(q): time.sleep(5) q.put(1) # 发送任务完成信号 print('slowf--- task done') def checkn(q): while 1: if not q.empty(): print('checkn', "T") break else: print('checkn', "F") time.sleep(1) def main(): q = Queue() p = Pool() p.apply_async(slowf, args=(q,)) p.apply_async(checkn, args=(q,)) p.close() p.join() if __name__ == '__main__': main()
这种方式更轻量,适合只需要传递状态信号的场景。
额外提醒
- 尽量避免在多进程中使用全局变量,因为进程间的内存隔离会让你的代码行为变得不可预测
- 如果是多线程场景,全局变量是共享的,但需要注意加锁防止竞态条件——不过你的问题是多进程,所以不适用这个点
内容的提问来源于stack exchange,提问作者Derek Kuo
相关产品推荐
相关产品推荐

