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

MacOS下Python3.9对比3.7 multiprocessing重复执行问题修复

问题根因

该现象不是代码bug,是Python 3.8及之后版本在macOS平台调整multiprocessing默认进程启动方式导致的:

  • Python 3.7及更早版本,macOS下multiprocessing默认使用fork模式创建子进程:该模式直接复制主进程当前内存状态生成子进程,不会从头重新执行主脚本代码。
  • Python 3.8开始,macOS平台默认启动方式改为spawn模式:该模式会启动全新的Python解释器进程,重新导入整个主脚本完成初始化,所有写在if __name__ == '__main__'判断块外的顶层代码,都会被每个子进程执行一次。8核CPU创建进程池时默认拉起8个工作进程,就会出现8次顶层代码重复执行的现象。
修复方案

优先推荐使用标准兼容写法,不建议强行改回fork模式:

  • 把所有仅需要主进程执行的逻辑,全部放到if __name__ == '__main__'保护块内部,避免子进程导入脚本时触发执行。比如原代码中第5行的顶层打印、脚本最后一行的退出打印,都属于这类逻辑,移入保护块即可解决重复执行问题。
  • 如果确实需要兼容旧逻辑,可以在创建进程池之前显式设置进程启动方式为fork,注意:该设置全局仅能调用一次,且macOS后续系统版本已废弃fork相关API,强行使用可能触发进程卡死、系统调用异常等问题,非必要不选择该方案:
import multiprocessing as mp
# 该行必须放在所有创建进程/进程池的逻辑之前
mp.set_start_method('fork')

修正后的可运行代码示例:

#!/usr/bin/python
from time import strftime
import multiprocessing as mp

# 函数定义放在顶层无影响,子进程导入时仅完成函数声明不会执行
def pullLast():  
    print(12345678998765432345678)
    return 1

def mprocULwork(uplist):
    ULsyms = [e for e in uplist if e is not None] 
    p_size = mp.cpu_count()
    pool = mp.Pool(processes=p_size, maxtasksperchild=400)
    pool_outputs = pool.map(ULProcess, ULsyms)
    pool.close()
    pool.join()
    del pool
    print (strftime("%H:%M:%S"), "Finished ULwork")

def ULProcess(symbol):
    pSet = 0
    print(pSet,symbol)
    
if __name__ == '__main__': 
    # 所有主进程专属执行逻辑全部放在该块内
    print(strftime("%H:%M:%S") + ' Run line5')
    pSet = 1
    symlist = ["G","Y","S"]
    ullist = symlist

    global lastPriceDF
    lastPriceDF = pullLast()

    mprocULwork(ullist)
    print (strftime("%H:%M:%S"), "post")
    print (strftime("%H:%M:%S"),  'Exiting....line last')
threading模块相关说明

threading模块不存在同类问题:

  • 线程是运行在同一个进程内部的执行单元,所有线程共享当前进程的内存空间和初始化状态,启动线程时不会启动新的解释器进程,也不会重新导入执行主脚本,无论哪个Python版本都不会出现这类顶层代码重复执行的问题。
  • Python 3.7到3.9版本的threading模块没有涉及启动逻辑的重构,不存在同类行为变更。

内容的提问来源于stack exchange,提问作者Merlin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 01:54:23