在Cura插件中实现Python多进程/多线程的方案咨询
__name__问题 问题背景
我正在开发一款用于修改3D打印G代码的Python脚本,原脚本使用multiprocessing实现多进程,代码如下:
if __name__ == '__main__': # MultiProcessing with Pool() as p: resultat = p.map(traitement_gcode_lineaire,liste_traitement) if len(resultat)!=0 : for result in resultat : fichier += result
单独运行脚本时工作正常,但集成到3D切片软件Cura的插件中后,__name__的值始终为'PostProcessingPlugin.PostProcessingPlugin.ModificationGcodeMultiProcessing'(ModificationGcodeMultiProcessing是脚本文件名),而非'__main__'。
尝试将判断条件改为if __name__ == 'PostProcessingPlugin.PostProcessingPlugin.ModificationGcodeMultiProcessing':,导致无限循环;换用multithreading时也遇到相同的__name__问题,现寻求该场景下实现多进程/多线程的可行方案。
注:traitement_gcode_lineaire是用于修改G代码的函数,liste_traitement是该函数所需参数的列表。
可行解决方案
方案1:使用spawn启动方式封装进程逻辑
Cura插件环境下,Python多进程默认的fork启动方式会重复加载模块引发循环,改用spawn启动方式,并将进程执行逻辑封装到独立函数中,避免模块级代码重复执行:
from multiprocessing import Pool, get_context def run_processing(): with get_context("spawn").Pool() as p: return p.map(traitement_gcode_lineaire, liste_traitement) # 在插件主逻辑中直接调用,无需依赖__name__判断 resultat = run_processing() if resultat: for result in resultat: fichier += result
spawn方式会启动全新的Python解释器,仅导入必要模块,从根源避免循环问题。
方案2:改用线程池(规避__name__依赖)
若G代码处理为IO密集型任务,线程池更轻量,且无需处理多进程的模块加载问题。直接使用concurrent.futures.ThreadPoolExecutor,无需依赖__name__判断:
from concurrent.futures import ThreadPoolExecutor with ThreadPoolExecutor() as executor: resultat = list(executor.map(traitement_gcode_lineaire, liste_traitement)) if resultat: for result in resultat: fichier += result
线程池在当前进程内运行,不会触发模块重复导入,自然不存在__name__相关的循环问题。
方案3:手动控制进程启动入口(备选)
若必须使用multiprocessing.Pool,可直接去掉__name__判断,将进程逻辑放在插件的执行流程中,确保仅被调用一次:
from multiprocessing import Pool # 在插件的业务逻辑节点直接执行,避免模块重复加载触发循环 with Pool() as p: resultat = p.map(traitement_gcode_lineaire, liste_traitement) if resultat: for result in resultat: fichier += result
此方案可靠性不如前两者,仅作为备选。
内容的提问来源于stack exchange,提问作者Totor

