Communicate with worker through client

조회 수: 7 (최근 30일)
guy sharon
guy sharon 2019년 9월 22일
답변: Thomas Falch 2025년 5월 15일
Hello!
I have an app (app designer/GUIDE) which calls a function that looks something like this
function func()
spmd
switch labindex
case 1
while (true)
% some code...
end
case 2
while (true)
% some code...
end
end
end
end
and I would like to be able to break out of the while loop for each workers of the spmd with a click of a button in the app, which means I have to send data from the client to the workers.
I know I can easily send data from the workers to the client, but I'm not sure about the reverse direction.
Please help, thanks!

답변 (2개)

Edric Ellis
Edric Ellis 2019년 9월 23일
I think it would be better to use parfeval or parfevalOnAll to do this. This way, you can simply cancel the future object returned from those calls to stop the worker execution. You could couple this with a parallel.pool.DataQueue to get the results back from the workers. Here's a simple example:
% Build a really simple "UI" - just a histogram and a button
pool = gcp();
fig = uifigure();
grid = uigridlayout(fig, [1, 2]);
ax = axes(uipanel(grid));
btn = uibutton(grid);
hist = histogram(ax, 'BinEdges', 0.5 + (0:pool.NumWorkers));
% Set up a DataQueue to let the workers send results back to the client
Q = parallel.pool.DataQueue();
% Each time a worker sends a piece of data to the client, append it
% to the histogram
listener = afterEach(Q, @(data) appendData(hist, data));
% Trigger the work on the workers, hook up the future to the button
% so that pressing the button cancels 'fut'.
fut = parfevalOnAll(@doWork, 0, Q);
btn.ButtonPushedFcn = @(~,~) cancel(fut);
%% function to do work on the workers
function doWork(Q)
task = getCurrentTask;
myId = task.ID;
while true
send(Q, myId);
pause(myId/4);
end
end
%% function to append data to the histogram
function appendData(hist, data)
hist.Data(end+1) = data;
end
  댓글 수: 3
Edric Ellis
Edric Ellis 2019년 9월 25일
labSend and labReceive can only be used inside spmd. Unfortunately, spmd is a synchronous construct on the client, so there's no way for the client to interrupt the workers.
guy sharon
guy sharon 2019년 9월 25일
So there is no way to both be able to communicate between workers and be able to stop all workers from the client?

댓글을 달려면 로그인하십시오.


Thomas Falch
Thomas Falch 2025년 5월 15일
From R2025a you can use the new "any-destination" PollableDataQueue to more easily communicate between the client and workers, or between different workers. (The existing PollableDataQueue can also do this, but this requires more elaborate setup, since you always need to create the queue on it's destination).
With the any-destination queue, you can implement a stop button for an spmd block like this:
queue = parallel.pool.PollableDataQueue(Destination="any")";
spmd
while true
doSomeWork()
% Check if we've got a stop message on the queue
[data, didReceive] = queue.poll()
if didReceive && strcmp(data, "stop")
break
end
end
end
% In GUI stop button callback
queue.send("stop")

카테고리

Help CenterFile Exchange에서 Environment and Settings에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by