parallel timers not executing as expected

3 views (last 30 days)
I am trying to run two parallel timers. Below is a minimal example.
I would expect (or wish) that timerCallback2 is executed when timerCallback1 is in pause mode. But the function seems to be blocking. I also tried to add some drawnow calls.
Is there any way to execute multiple timer callbacks while another is still running, or is this intended behavior? Does MATLAB not process the event queue while another event is still running? Or are there different event queues for timer events and GUI events?
Thank you for your help!
timer1 = timer(Name="timer1", ExecutionMode="fixedSpacing", BusyMode="queue", TimerFcn=@timerCallback1, TasksToExecute=3, Period=1);
start(timer1)
timer2 = timer(Name="timer2", ExecutionMode="fixedSpacing", BusyMode="queue", TimerFcn=@timerCallback2, TasksToExecute=30, Period=0.1);
start(timer2)
function timerCallback1(~,~)
disp("start T1...")
pause(2)
disp("end T1...")
end
function timerCallback2(~, ~)
disp(" start T2...")
pause(0.05)
disp(" end T2...")
end
%% Output is:
% start T1...
% end T1...
% start T2...
% end T2...
% start T2...
% end T2...
% start T2...
% end T2...
% start T2...
% end T2...
% start T2...
% end T2...
% start T2...
% end T2...
% start T2...
% end T2...
% start T1...
% end T1...
% start T2...
% end T2...
% start T2...
% and so on....

Accepted Answer

Pavan Sahith
Pavan Sahith on 7 Aug 2024
Edited: Pavan Sahith on 7 Aug 2024
Hello Marco,
To run multiple timer callbacks in parallel in MATLAB, you can try using the 'parfeval' function from the Parallel Computing Toolbox. This approach allows for non-blocking execution of functions, which can be beneficial in scenarios where you need concurrent timer functionality.
You can refer to the following sample code and see if it helps :
% Initialize parallel pool
if isempty(gcp('nocreate'))
parpool;
end
% Create data queues for communication
dq1 = parallel.pool.DataQueue;
dq2 = parallel.pool.DataQueue;
% Define callbacks to handle incoming data
afterEach(dq1, @(data) disp(data));
afterEach(dq2, @(data) disp(data));
% Start parallel execution
f1 = parfeval(@timerTask1, 0, dq1);
f2 = parfeval(@timerTask2, 0, dq2);
function timerTask1(dq)
for i = 1:3
send(dq, "start T1...");
pause(2); % Simulate long processing
send(dq, "end T1...");
pause(1); % Period between executions
end
end
function timerTask2(dq)
for i = 1:30
send(dq, " start T2...");
pause(0.05); % Simulate shorter processing
send(dq, " end T2...");
pause(0.1); % Period between executions
end
end
Note that you need the Parallel Computing Toolbox for this approach to work.
Consider referring to the following MathWorks documentation to know more
Hope you find this helpful!
  1 Comment
Marco
Marco on 9 Aug 2024
Thank you very much for your help!
Your code works well for the given example, and I will consider using parfeval for my application. Unfortunately, this requires a bit more work.
My application is an App Designer app that uses TCP connections. Reading and writing can be triggered by button events and also by timers to send keep-alive messages. Occasionally, my app or the entire MATLAB session crashes without any error message. I strongly believe this occurs when timer events interrupt code execution at very unlucky places, possibly somewhere within TCP send() or read() functions.
I think this behavior should be highlighted in the documentation with a big red exclamation mark. Instead, there is a misleading tip: "To force the execution of the callback functions in the event queue, include a call to the drawnow function. The drawnow function flushes the event queue."
But since timer events themselves cannot be interrupted by pause or drawnow (for example, to wait for a TCP message to arrive), this makes asynchronous programming difficult and leads to ugly workarounds.

Sign in to comment.

More Answers (0)

Categories

Find more on Parallel Computing Fundamentals in Help Center and File Exchange

Products


Release

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!