You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:11:48