I think it's possible to do this sort of thing by getting the workers to create a parallel.pool.PollableDataQueue, and getting the client to send messages to the worker. It's a bit awkward to set up, and in the example below, I'm going to use a parallel.pool.Constant to get the worker to hold onto the queue instance. The general plan is this:
- Get the worker to construct a pollable dataqueue
- Send the dataqueue instance back to the client
- Set the worker off into an loop waiting for messages from the client
- Send messages from the client to get the worker to do stuff
- When done, get the client to send a "poison pill" which gets the worker to return the result.
Note the code below only works for a pool of size 1. To run on a larger pool, you would need to use parfevalOnAll rather than parfeval, and you'd also need to manage the multiple queues from the workers.
if isempty(gcp())
parpool('local', 1);
end
workerQueueConstant = parallel.pool.Constant(@parallel.pool.PollableDataQueue);
workerQueueClient = fetchOutputs(parfeval(@(x) x.Value, 1, workerQueueConstant));
future = parfeval(@doStuff, 1, workerQueueConstant);
for idx = 1:10
send(workerQueueClient, idx);
end
send(workerQueueClient, []);
fetchOutputs(future)
function out = doStuff(qConstant)
q = qConstant.Value;
out = 0;
while true
data = poll(q, Inf);
if isempty(data)
return
else
out = out + data;
end
end
end
Best Answer