How to successfully spawn and synchronize threads in matlab?

8 views (last 30 days)
I'm trying to call functions every 3 seconds during a loop however I'm having difficulty having the functions go off. Currently parfeval and its function does nothing. Here is the code:
%% Recording events
delete(gcp('nocreate'))
q = parallel.pool.DataQueue;
pool = gcp();
while notDone
%% Termination clause
if t.Bytesavailable < 12 %if there's not even enough data available to read the header
cutoffcounter = cutoffcounter + 1; %take a step towards terminating the whole thing
if cutoffcounter == 3000 %and if 3000 steps go by without any new data,
notDone = 0; %terminate the loop.
end
disp('no bytes available')
pause(0.001)
continue
else %meaning, unless there's data available.
cutoffcounter = 0;
end
% Read the packet
data = uint8(fread(t, 12))'; % Loads the first 12 bytes of the first packet, which should be the header
data = [data, uint8(fread(t, double(typecast(fliplr(data(7:8)), 'uint16'))))']; % Loads the full packet, based on the header
lengthdata = length(data);
if all(ismember(headerStart,data)) % Checks if the packet contains the header
packetType = data(6); %this determines whether it's an event or sensor packet.
%% Event Packet. This includes the greeting packet
if packetType == 5
disp("event packet!")
end
%% EEG sensor packet
if packetType == 1
Timestamp = swapbytes(typecast(data(13:16),'single'));
EEGdata = swapbytes(typecast(data(24:lengthdata),'single'));
EEGdata = EEGdata(1:7);
%% Write data to text file
fmtSpec = repmat('%f, ',1, 7);
fprintf(textFile, '%f, ', Timestamp);
fprintf(textFile, fmtSpec, EEGdata);
if rem(Timestamp, 3) == 0
fprintf(textFile, '1, flash light start');
future(1) = parfeval(pool, @do_action, 0, 0);
end
if Timestamp > 3
afterEach(future, @print_action, 0);
end
fprintf(textFile, '\n');
end
end
end
The idea is that at if rem(Timestamp, 3) == 0 I spawn a thread that does the function, and records when it started and ended into a file. I would also like to know about synchronization when it comes to printing (making sure I don't print after a newline for example)

Answers (1)

Prathamesh
Prathamesh on 30 Jul 2025
I understand that you are trying to run a function every 3 seconds, but it sometime starts the function too many times at once and loses track of them.
The `parfeval` function is used to run tasks asynchronously on a parallel pool, but in your code, it gets called every time `rem(Timestamp,3)==0` is true, which can happen repeatedly if `Timestamp` increases by less than 1 each loop. This can lead to multiple overlapping tasks being started unintentionally. Additionally, setting up `afterEach` inside the loop for each future is not recommended, it should be attached once to properly handle task completions. Lastly, the `future` variable should be managed carefully to avoid overwriting and losing track of running tasks.
Below are steps to solve the issue:
  • Only start your function when you cross a new 3-second mark, not every time ‘rem(Timestamp,3)==0’ is true.
  • Keep track of the last time you triggered the function to avoid repeats.
  • Use a ‘DataQueue’ for safe communication and logging from worker functions back to the main program.
  • Only write to your file from the main thread to prevent mixed-up data.
  • Set up ‘afterEach’ once, not inside the loop, to handle results from background tasks properly.
Below is an example code which initiates three background tasks, each simulating a thread that pauses for a random duration between 2 and 7 seconds while printing status messages. The main script concurrently waits for a maximum of 5 seconds; any tasks still running after this timeout are then canceled, with their cancellation noted in the output.
% Start parallel pool if not already started
pool = gcp('nocreate');
if isempty(pool)
pool = parpool;
end
% Number of parallel tasks to run
numTasks = 3;
% Start time
startTime = tic;
% Launch tasks (threads) asynchronously
for i = 1:numTasks
futures(i) = parfeval(@backgroundTask, 0, i); % 0 outputs, pass task number
end
% Set maximum allowed time (in seconds)
maxTime = 5;
% Main loop: wait until time is up or all tasks are done
while toc(startTime) < maxTime
% Check if all tasks are finished
if all([futures.State] == "finished")
disp('All tasks completed.');
break;
end
pause(0.1); % Prevent busy waiting
end
% If time is up and some tasks are still running, cancel them
for i = 1:numTasks
if futures(i).State ~= "finished"
cancel(futures(i));
fprintf('Task %d cancelled due to timeout.\n', i);
end
end
disp('Main script finished.');
% Background task function
function backgroundTask(taskID)
fprintf('Task %d started.\n', taskID);
pauseTime = randi([2,7]); % Each task takes 2-7 seconds
pause(pauseTime);
fprintf('Task %d finished after %d seconds.\n', taskID, pauseTime);
end
Refer below documentation link for ‘parfeval’

Tags

Products


Release

R2020b

Community Treasure Hunt

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

Start Hunting!