MEX-функции могут вызвать MATLAB® от созданных пользователями потоков с помощью Engine C++ асинхронный API.
Вызовы, выполненные асинхронно к MATLAB на отдельном потоке, не делают выполнения блока MATLAB. MEX-функция может возвратиться к посдказке MATLAB, в то время как выполнение на пользовательском потоке продолжается. Можно вызвать функции MATLAB от пользовательского потока через механизм асинхронный API или от командной строки. MATLAB ставит команды в очередь от каждого потока и выполняет их в полученном заказе.
Чтобы вызвать MATLAB от созданных пользователями потоков, задайте MEX-функцию, которая использует эти методы:
Запустите поток выполнения для асинхронных вызовов функции, например, с C++ 11 функций std::async
.
Используйте Engine API для C++, чтобы выполнить асинхронные вызовы к MATLAB.
Эта MEX-функция отображает текущую дату и время в окне фигуры MATLAB. Дата/строка времени обновляет каждую секунду. MEX-функция возвращается к посдказке MATLAB, в то время как асинхронные обновления продвигаются поток, созданный вызовом std::async
.
Функция dateTimeWindow.m
(код MATLAB) создает окно рисунка и текстовый объект uicontrol
, чтобы отобразить дату и время. Свойства Tag
uicontrol и фигуры содержат идентификаторы, используемые, чтобы получить доступ к этим объектам от MEX-функции.
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
Эта MEX-функция задает функцию DisplayDateTime()
, чтобы выполнить эти операции:
Вызывает функцию MATLAB dateTimeWindow.m
, чтобы настроить отображение окна рисунка и текста.
Обновляет отображение даты и времени однажды в секунду путем присвоения вывода выражения datestr(now)
к свойству String
uicontrol.
Тестирует валидность объекта uicontrol определить, было ли окно рисунка закрыто.
Выходит из цикла обновления, если окно и текстовый объект больше не существуют.
MEX-функция вызывает std::async
, чтобы запустить функцию членства DisplayDateTime()
на отдельном потоке.
/* 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();
}
}
};
Чтобы использовать MEX-функцию, сохраненную в качестве mexDateTime.cpp
, используйте команду mex
, чтобы создать программу.
mex -setup c++ mex mexDateTime.cpp mexDateTime
MEX-функция блокирует файл MEX, чтобы предотвратить попытки перекомпилировать MEX-функцию, в то время как отдельный поток все еще активен. MEX-функция разблокировала себя, когда вы заканчиваете выполнение.
Чтобы закончить выполнение на отдельном потоке, закройте окно рисунка, содержащее текст даты и времени, или вызовите MEX-функцию с входным параметром. Например:
mexDateTime close
figure
| matlab::mex::Function
| uicontrol