Python multiprocessing场景使用全局变量存储回调结果是否合理?
首先回答你第一个问题:当前用全局变量的方案不算合理
你这段代码能正常拿到结果,本质是因为map_async传入的回调函数cTest是在主进程中执行的,并没有跨进程修改全局变量,所以才没有出现多进程地址空间隔离导致的变量不更新问题。但这个方案存在很明显的缺陷:
- 代码可读性差,全局变量的修改逻辑隐式藏在回调里,后续维护很难快速定位变量来源
- 无法复用逻辑,只要同时跑多个不同的进程池任务,全局变量
message会被不同任务的回调覆盖,直接出现数据错误 - 扩展性差,后续如果要针对不同任务存不同的汇总结果,全局变量会越来越臃肿,容易出隐患
更优的实现方案
方案1:直接获取异步任务的返回结果(最推荐,适合你的场景)
map_async返回的AsyncResult对象直接调用get()方法就能拿到所有任务的返回值列表,完全不需要全局变量和回调,代码逻辑清晰直观:
import multiprocessing def mTest(name): print(name) return("t" + name) if __name__ == '__main__': testList = ['Jake', 'Jake', 'Jake', 'Jill', 'Jake', 'Jake'] pool = multiprocessing.Pool(processes=2) # 直接获取返回值,不需要回调和全局变量 result_list = pool.map_async(mTest, testList).get() pool.close() pool.join() message = "-".join(result_list) print("-->" + message)
运行结果和你原来的代码完全一致。
方案2:如果确实需要用回调,用绑定的容器替代全局变量
如果你的业务场景需要边执行边回调处理结果,可以用functools.partial把列表这类可变容器绑定到回调函数里,避免用全局变量:
import multiprocessing from functools import partial def cTest(result_container, m): result_container.extend(m) def mTest(name): print(name) return("t" + name) if __name__ == '__main__': testList = ['Jake', 'Jake', 'Jake', 'Jill', 'Jake', 'Jake'] result_container = [] # 把存储结果的列表绑定到回调函数 callback = partial(cTest, result_container) pool = multiprocessing.Pool(processes=2) pool.map_async(mTest, testList, 1, callback) pool.close() pool.join() message = "-".join(result_container) print("-->" + message)
内容的提问来源于stack exchange,提问作者BenW
相关产品推荐
相关产品推荐

