- 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.
How to successfully spawn and synchronize threads in matlab?
8 views (last 30 days)
Show older comments
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)
0 Comments
Answers (1)
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:
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’
0 Comments
See Also
Categories
Find more on Matrix Indexing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!