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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 01:58:09