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=-1Done...data=-1-1.000000data=-1-1.000000data=-1-1.000000data=-1-1.000000data=-1-1.000000data=-1-1.000000data=-1-1.000000data=-1-1.000000data=-1-1.000000data=-1-1.000000data=0data=1data=2data=3data=4data=5data=6data=7data=8data=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 testClassmethods(Static) function out = start() TestSource.processSubscription('test',-1); MexThreadTest() for i=1:10 fprintf('%f\n',TestSource.processSubscription('test')) pause(1) end endendend
classdef TestSourcemethods(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 endendend
Best Answer