Mex thread is being blocked by running function.

2 views (last 30 days)
Update: I found an easier example. If I run the example that is listed at https://www.mathworks.com/help/matlab/matlab_external/call-matlab-from-user-threads-in-mex-function.html And call pause(10) from the command line, the asyn update stops until the pause completes. Why is this, how to keep this from happening?
I am using the C++ mex functions to run something async, and it updates data in the workspace. It works fine unless something else is running.
For example if I run the following loop the timestamp isn't getting updated, but if I call getTimestamp() from command line, it is updated. How can I have matlab yield instead of using pause? I have included some sample code, and my output. What I would have expected is the interleaving of the setting and getting of the data, but instead the one loop runs for 10 seconds, and then the second loop runs for 10 seconds.
Test output:
>> testClass.start()
data=-1
Done...
data=-1
-1.000000
data=-1
-1.000000
data=-1
-1.000000
data=-1
-1.000000
data=-1
-1.000000
data=-1
-1.000000
data=-1
-1.000000
data=-1
-1.000000
data=-1
-1.000000
data=-1
-1.000000
data=0
data=1
data=2
data=3
data=4
data=5
data=6
data=7
data=8
data=9
#include "mex.hpp"
#include "mexAdapter.hpp"
#include <thread>
#include <codecvt>
class MexFunction : public matlab::mex::Function {
private:
std::future<void> voidStdFuture;
std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();
bool isRunning = false;
public:
void ProcessSubscription()
{
matlab::data::ArrayFactory factory;
std::vector<matlab::data::Array> args;
args.push_back(factory.createScalar("test"));
for(int i = 0; i < 10; i++)
{
std::vector<matlab::data::Array> args;
args.push_back(factory.createScalar("test"));
args.push_back(factory.createScalar(i));
// std::cout << "channel = " << channel << " size= " << data.size() << std::endl;
matlabPtr->fevalAsync(u"TestSource.processSubscription", 0, std::move(args));
std::this_thread::sleep_for(std::chrono::seconds(1));
}
std::cout << "Done..." << std::endl;
}
void operator()(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs) {
std::async(std::launch::async, &MexFunction::ProcessSubscription, this);
}
};
classdef testClass
methods(Static)
function out = start()
TestSource.processSubscription('test',-1);
MexThreadTest()
for i=1:10
fprintf('%f\n',TestSource.processSubscription('test'))
pause(1)
end
end
end
end
classdef TestSource
methods(Static)
function out = processSubscription(channel, data)
persistent test;
if strcmp(channel,'test') == 1
if nargin == 2
test = data;
end
out = test;
fprintf('data=%d\n',out)
else
fprintf('Unknown Message Type Received %s\n', channel);
end
end
end
end

Accepted Answer

Ran Chen
Ran Chen on 5 Feb 2019
In MATLAB R2018b, while C++ MEX supports calling MATLAB from a user thread, there is only one MATLAB thread that can process requests.'fevalAsync' will not create a new MATLAB thread in the C++ process. The development team has been informed of the enhancement, and in a future release of MATLAB, the 'fevalAsync' may bypass the 'pause" so MATLAB can process the request when it is not doing anything.
If you are looking for a way to run several MATLAB scripts in parallel, please consider using Parallel Computing Toolbox.
https://www.mathworks.com/help/distcomp/

More Answers (0)

Tags

Products


Release

R2018b

Community Treasure Hunt

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

Start Hunting!