Matlab Python Engine freezes if a matlab script is running
Show older comments
Hi, guys, how are you doing?
I'm facing a strange scenery that's driving me crazy...
Due to problems between Numpy and embedded Python interpreter inside a SFunction (everytime I call 'clear mex' and try to reload the SFunction, Matlab crashes due to issues with importing numpy more than once). Considering it's an old problem without solution (there are discussions about it since 2010) I decided to go through another approach and then I decided to implement a solution using the Python API provided by Matlab Python engine.
The first problem I found is:
1) When I call a Python script from Matlab (i.e "py.PY_FILE.PY_METHOD") and this Python script has a 'callback approach' (i.e try to connect to the same Matlab instance shared before), the connection fails.
mlInstances = mlEngine.find_matlab()
if len(mlInstances) == 1:
try:
if self.engineName == '':
future = mlEngine.connect_matlab(mlInstances[0], background=True)
% Connection attempt failed here
self.matlabEngineHandle = future.result()
else:
if self.engineName != mlInstances[0]:
print(Fore.YELLOW + 'Engine name ' + self.engineName + ' is different from Matlab engine found (' + mlInstances[0] + ')')
self.matlabEngineHandle = mlEngine.connect_matlab(mlInstances[0])
except Exception as EngineError:
print(Fore.RED + EngineError)
return False
So, is there any way of calling back and interact with Matlab in this approach?
Looking for an alternative, I built a 'workaround' using an UDP approach. Before calling Matlab script, I run an endless Python script that open an UDP port to wait for a message (that will be send by Matlab script). When Matlab sends this UDP message and Python receives and processes it, the 'callback' approach (interact with Matlab workspace, for example, as shown below) works flawlessly.
import matlab.engine as mlEngine
self.matlabEngineHandle = mlEngine.connect_matlab(mlInstances[0])
def parseMsg(self, msg):
if self.matlabEngineHandle.exist('waitControlVar', 'var'):
self.matlabEngineHandle.workspace['waitControlVar'] = 1
The main problem in this approach is: if I use an endless loop in Matlab to wait to Python script ends (dealing with a condition variable in workspace, for example), Python script will hang if matlabEngine is called.
while true
% Wait until trimming process to finish or time out has been reached
if ~waitControlVar
out = 1;
break;
else
if toc(startTime) > timeLimit
out = 2;
break;
end
end
pause(1);
end
So, is there any way of solving it without using Parallel Computing Toolbox? I tried to understand why I don't have this behavior when using the C++ API (used in SFunction approach).
Thanks in advance, guys!!!
5 Comments
Answer from AI:
The reason for this behavior comes down to MATLAB’s single-threaded architecture and how the matlab.engine communicates with shared sessions.
When MATLAB is stuck in a while true loop (even with a pause(1)), MATLAB's main execution thread is completely occupied. Because the MATLAB Python Engine sends synchronous commands to that same instance via IPC (Inter-Process Communication), Python blocks waiting for MATLAB to acknowledge and execute the command. However, MATLAB cannot process it because it is trapped in your loop, causing a classic deadlock.
In your original C++ API (S-Function) approach, Python was running embedded inside the same process space, giving it a different execution context.
Here are the best ways to resolve this without using the Parallel Computing Toolbox:
Solution 1: Use drawnow instead of pause (The Easiest Fix)
In modern MATLAB versions, pause does not always flush the external engine's event queue. Replacing it with drawnow forces MATLAB to process its pending event queue. This opens a brief window for the Python engine to step in and alter the workspace variable.
Modify your MATLAB loop like this:
matlab
while true
% Force MATLAB to process pending external engine events
drawnow;
if ~waitControlVar
out = 1;
break;
else
if toc(startTime) > timeLimit
out = 2;
break;
end
end
pause(0.1); % Shorter pause for better responsiveness
end
Solution 2: Two-Way UDP Communication (Highly Recommended)
Since you already have a working UDP pipeline from MATLAB to Python, you should completely abandon the MATLAB Engine API for the "return channel". Writing directly to the workspace via self.matlabEngineHandle.workspace breaks the single-thread design.
Instead, let MATLAB actively listen for a UDP packet from Python, rather than polling a workspace variable.
MATLAB Side (Receiver):
matlab
% Create a UDP port receiver
u = udpport("LocalPort", 51234);
startTime = tic;
out = 0;
while true
% Check if data has arrived in the UDP buffer
if u.NumBytesAvailable > 0
data = read(u, u.NumBytesAvailable, "string");
if contains(data, "DONE")
out = 1;
break;
end
end
if toc(startTime) > timeLimit
out = 2;
break;
end
pause(0.1);
end
Python Side (Sender):
Instead of touching the engine, Python sends a UDP packet back to MATLAB when finished processing:
python
import socket
def parseMsg(self, msg):
# ... Your Python processing logic here ...
# Send the completion trigger back to MATLAB via UDP
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto(b"DONE", ("127.0.0.1", 51234))
Why this is better: It decouples the two environments entirely, eliminates any possibility of a deadlock, and is extremely fast.
Solution 3: Asynchronous Evaluation in Python (background=True)
If you must use the Engine API to modify variables, you have to execute the MATLAB command asynchronously from Python. You attempted this during connection, but the deadlock actually happens during the variable assignment.
Directly accessing engine.workspace['var'] is synchronous and blocks Python. Instead, trigger an asynchronous eval:
python
# In Python: Set the variable asynchronously
future = self.matlabEngineHandle.eval("waitControlVar = 1;", nargout=0, background=True)
# CRITICAL: Do NOT call future.result() here.
# Calling .result() will block Python until MATLAB responds, triggering the deadlock again.
Because background=True is set, Python drops the command into MATLAB's pipeline and immediately continues executing its own code. When paired with drawnow on the MATLAB side (Solution 1), MATLAB will safely process it.
If nothing works, contact support:
Is there any chance of success if I use 'drawnow approach' in R2026a?
I didn't mention the MATLAB version when asking AI. So my guess is that if the 'drawnow approach' didn't work in 2025a, it won't work in R2026a, either.
Consider contacting support for your non-trivial technical question:
Pedro
27 minutes ago
Just for clarification:
Members of this MATLAB Answers forum are MATLAB users (like me) and not MathWorks employees. I'd be glad if my suggestion was successful, but for more complicated technical questions, the official MATLAB support is often better suited:
Of course, you can come back here, but I have to fully rely on AI's answers: I've not yet coded a MATLAB - Python coupling.
Answers (0)
Categories
Find more on Call MATLAB from Python in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!