Python Multiprocessing Semaphore失效问题排查与解决请求
解决Windows下Python2.7多进程Pool打印混乱的信号量问题
问题根源
你遇到的核心问题是Windows系统下Python多进程的启动机制导致全局信号量不共享。在Windows上,multiprocessing.Pool会通过创建新进程执行任务,每个子进程都会重新导入你的主模块——这意味着全局定义的rightofway = multiprocessing.Semaphore(1)会在每个子进程中被重新实例化,每个进程拿到的都是独立的信号量,自然起不到跨进程互斥的作用。
解决方案:使用Manager创建跨进程共享的信号量
要让信号量在所有子进程中共享,你需要借助multiprocessing.Manager()。Manager会启动一个独立的管理进程,所有子进程通过代理访问同一个同步原语,这样就能实现真正的跨进程互斥。
以下是修改后的可运行代码:
import multiprocessing from functools import partial def writenum(rightofway, number): rightofway.acquire() print("[+] - " + str(number)) rightofway.release() return def main(): starting = 0 ending = 50 num_list = range(starting, ending) # 创建Manager来生成跨进程共享的信号量 with multiprocessing.Manager() as manager: rightofway = manager.Semaphore(1) # 使用partial把信号量绑定到函数参数上 wrapped_func = partial(writenum, rightofway) pool = multiprocessing.Pool(10) pool.map(wrapped_func, num_list) pool.close() pool.join() if __name__ == '__main__': main()
关键修改说明
- 用
manager.Semaphore(1)替代全局信号量:这个信号量由Manager进程管理,所有子进程共享同一个实例。 - 使用
functools.partial包装函数:因为pool.map只能传递一个迭代参数,我们用partial把信号量提前绑定到writenum的第一个参数上,这样子进程执行时就能拿到共享的信号量。 - 显式调用
pool.close()和pool.join():确保所有子进程完成后再退出主进程,这是良好的多进程编程习惯。
额外优化(可选)
如果担心print语句的缓冲问题(虽然同步后大概率不会),可以在打印时强制刷新输出:
print("[+] - " + str(number)) import sys sys.stdout.flush()
这样就能保证每个进程的打印内容完整输出,不会出现重叠混乱的情况。
内容的提问来源于stack exchange,提问作者Danegraphics
相关产品推荐
相关产品推荐

