Matlab R2022b引擎在Python多进程池调用中卡死求解决方案
问题描述
我使用Python 3.8.5开发代码,在Ubuntu 20.04系统下通过Matlab引擎调用R2018a处理数据,此前用multiprocessing.Pool开启20线程加速,代码运行完全正常。但升级Matlab至R2022b后,相同代码在Pool内调用Matlab引擎时出现卡死:卡在"Starting Matlab engine"环节,无法继续执行。
单独调用Matlab引擎、单独使用Pool处理普通任务均正常,仅在Pool内调用引擎时出现卡死,在Jupyter Notebook和终端运行结果一致。
示例代码
import multiprocessing from multiprocessing import Pool import matlab.engine import time print("defining function ...") def function88(j): print("cal result1 ... ") result1 = j**2 print(result1) print("Starting Matlab engine...") eng = matlab.engine.start_matlab() print("Matlab engine started...") print("Calling Matlab function...") out = eng.test(j) print("Matlab function output:") print(out) return result1 print("calling pool ...") pool = multiprocessing.Pool(1) print("calling pool.map") time.sleep(3) result = pool.map(function88, range(10)) print("printing result") print(result)
运行现象
defining function ...
calling pool ...
calling pool.map
cal result1 ...
0
Starting Matlab engine...
程序卡在上述环节,无法输出Matlab函数结果。
解决方案
1. 改用spawn模式创建进程池
Matlab R2022b引擎与Python默认的fork多进程模式存在兼容性冲突,改用spawn模式启动子进程可解决该问题。修改代码如下:
import multiprocessing from multiprocessing import Pool import matlab.engine import time print("defining function ...") def function88(j): print("cal result1 ... ") result1 = j**2 print(result1) print("Starting Matlab engine...") eng = matlab.engine.start_matlab() print("Matlab engine started...") print("Calling Matlab function...") out = eng.test(j) print("Matlab function output:") print(out) return result1 if __name__ == '__main__': print("calling pool ...") # 使用spawn上下文创建进程池 ctx = multiprocessing.get_context('spawn') pool = ctx.Pool(1) print("calling pool.map") time.sleep(3) result = pool.map(function88, range(10)) print("printing result") print(result)
注意:spawn模式下,主进程的执行代码必须放在if __name__ == '__main__':块内,避免子进程重复执行初始化逻辑。
2. 预启动Matlab引擎并复用(性能优化)
若频繁创建Matlab引擎影响效率,可在主进程预先启动会话,子进程通过连接复用:
import multiprocessing from multiprocessing import Pool import matlab.engine import time def function88(j): print("cal result1 ... ") result1 = j**2 print(result1) print("Connecting to Matlab engine...") # 连接到主进程预启动的会话 eng = matlab.engine.connect_matlab('shared_matlab') print("Connected to Matlab engine...") print("Calling Matlab function...") out = eng.test(j) print("Matlab function output:") print(out) return result1 if __name__ == '__main__': print("Pre-starting Matlab engine in main process...") # 启动Matlab并共享会话 eng = matlab.engine.start_matlab("-nodisplay") eng.matlab.engine.shareEngine('shared_matlab', nargout=0) print("calling pool ...") ctx = multiprocessing.get_context('spawn') pool = ctx.Pool(1) print("calling pool.map") time.sleep(3) result = pool.map(function88, range(10)) print("printing result") print(result) # 关闭主进程的Matlab引擎 eng.quit()
该方式可减少引擎启动开销,但需注意多进程并发调用同一引擎时可能需要加锁,避免冲突。
3. 验证环境与权限
- 确保Matlab安装目录已加入系统
PATH环境变量,终端执行matlab -nodisplay测试能否正常启动无界面Matlab会话。 - 确认当前用户拥有启动Matlab进程的权限,避免因权限不足导致引擎启动失败。
内容的提问来源于stack exchange,提问作者Parand
相关产品推荐
相关产品推荐

