Call MATLAB from Separate Threads in MEX Function
MEX functions can call MATLAB® from user-created threads using the C++ Engine asynchronous API.
Calls made asynchronously to MATLAB on a separate thread do not block MATLAB execution. The MEX function can return to the MATLAB prompt while execution on the user thread continues. You can call MATLAB functions from the user thread via the engine asynchronous API or from the command prompt. MATLAB queues the commands from each thread and executes them in the order received.
Communicating with MATLAB from Separate Threads
To call MATLAB from user-created threads, define a MEX function that uses these techniques:
Start a thread of execution for asynchronous function calls, for example with the C++11
std::async
function.Use the C++ Engine API to make asynchronous calls to MATLAB.
Example to Update the Display of Text
This MEX function displays the current date and time in a MATLAB figure window. The date/time string updates every second. The MEX
function returns to the MATLAB prompt while the asynchronous updates continue on the thread created
by the call to std::async
.
The dateTimeWindow.m
function (MATLAB code) creates a figure window and a uicontrol
text object to display
the date and time. The Tag
properties of the uicontrol and the
figure contain identifiers used to access these objects from the MEX
function.
function dateTimeWindow windowHandle = figure('MenuBar','none',... 'ToolBar','none',... 'Name','Current Date and Time',... 'NumberTitle','off',... 'Units','normalized',... 'Position',[.01 .01 .25 .05],... 'Tag','mexDateTimeHandle',... 'HandleVisibility','off'); uicontrol('Parent',windowHandle,... 'Style','text',... 'Tag','date_time',... 'String',datestr(now),... 'Units','normalized',... 'Position',[0 0 1 1],... 'FontSize',28); end
This MEX function defines the DisplayDateTime()
function to
perform these operations:
Calls the
dateTimeWindow.m
MATLAB function to set up the figure window and text display.Updates the display of the date and time once per second by assigning the output of the expression
datestr(now)
to the uicontrolString
property.Tests the validity of the uicontrol object to determine if the figure window has been closed.
Exits the update loop if the window and text object no longer exist.
The MEX function calls std::async
to run the
DisplayDateTime()
member function on a separate
thread.
/* Uses asynchronous Engine API to display date-time string
* Calls MATLAB dateTimeWindow.m function to create figure
* and uicontrol objects. Updates the date and time once
* per second. Run asynchronously on a separate thread
*/
#include "mex.hpp"
#include "mexAdapter.hpp"
#include <thread>
#include <future>
class MexFunction : public matlab::mex::Function {
private:
std::future<void> voidStdFuture;
std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();
bool isRunning = false;
public:
void DisplayDateTime( ) {
matlab::data::ArrayFactory factory;
matlabPtr->evalAsync(u"dateTimeWindow;");
while (isRunning) {
matlabPtr->evalAsync(u"set(findall(0,'Tag','date_time'),
'String',datestr(now));");
std::vector<matlab::data::Array> args({
factory.createScalar<double>(0),
factory.createCharArray("Tag"),
factory.createCharArray("date_time"),
});
matlab::engine::FutureResult<matlab::data::Array> fresult;
fresult = matlabPtr->fevalAsync(u"findall", args);
matlab::data::Array result = fresult.get();
isRunning = !result.isEmpty();
if (!isRunning) { matlabPtr->evalAsync(u"mexDateTime close"); }
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
void operator()(matlab::mex::ArgumentList outputs,
matlab::mex::ArgumentList inputs) {
if (inputs.size() == 0) {
mexLock();
if(!isRunning) {
isRunning = true;
voidStdFuture = std::async(std::launch::async,
&MexFunction::DisplayDateTime, this);
}
}
else {
isRunning = false;
matlabPtr->eval(u"close(findall(0,'Tag','mexDateTimeHandle'))");
mexUnlock();
}
}
};
To use the MEX function saved as mexDateTime.cpp
, use the mex
command to build the
program.
mex -setup c++ mex mexDateTime.cpp mexDateTime
The MEX function locks the MEX file to prevent attempts to recompile the MEX function while the separate thread is still active. The MEX function unlocks itself when you end execution.
To end execution on the separate thread, close the figure window containing the date and time text or call the MEX function with an input argument. For example:
mexDateTime close
See Also
matlab::mex::Function
| uicontrol
| figure