Вызовите MATLAB от отдельных потоков в MEX-функции

MEX-функции могут вызвать MATLAB® от созданных пользователями потоков с помощью Engine C++ асинхронный API.

Вызовы, выполненные асинхронно к MATLAB на отдельном потоке, не делают выполнения блока MATLAB. MEX-функция может возвратиться к подсказке MATLAB, в то время как выполнение на пользовательском потоке продолжается. Можно вызвать функции MATLAB от пользовательского потока через механизм асинхронный API или от командной строки. MATLAB ставит команды в очередь от каждого потока и выполняет их в полученном заказе.

Связь с MATLAB от отдельных потоков

Чтобы вызвать MATLAB от созданных пользователями потоков, задайте MEX-функцию, которая использует эти методы:

  • Запустите поток выполнения для асинхронных вызовов функции, например, с C++ 11 std::async функция.

  • Используйте Engine API для C++, чтобы выполнить асинхронные вызовы к MATLAB.

Пример, чтобы обновить отображение текста

Эта MEX-функция отображает текущую дату и время в графическом окне MATLAB. Дата/строка времени обновляется каждую секунду. MEX-функция возвращается к подсказке MATLAB, в то время как асинхронные обновления продвигаются поток, созданный вызовом std::async.

dateTimeWindow.m функция (код MATLAB) создает окно рисунка и a 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() функция, чтобы выполнить эти операции:

  • Вызывает dateTimeWindow.m Функция MATLAB, чтобы настроить отображение окна рисунка и текста.

  • Обновляет отображение даты и времени однажды в секунду путем присвоения выхода выражения datestr(now) к uicontrol String свойство.

  • Тестирует валидность объекта 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

Смотрите также

| |

Похожие темы