#c #multithreading #matlab #printf #mex
#c #многопоточность #matlab #printf #mex
Вопрос:
Я изменил пример программы, чтобы продемонстрировать проблему: она печатает строку каждую секунду. Проблема в том, что сообщения появляются в окне командной строки после того, как MATLAB возвращается в состояние ожидания (все сразу). Если он вызывается из командной строки и MATLAB возвращается в режим ожидания, сообщения появляются в окне командной строки:
mexFile;
Но в этом случае:
mexFile; while 1; end;
Сообщения появляются после того, как я прерываю бесконечный цикл с помощью ^C.
Вот мой исходный код. Он использует feval("fprintf"...)
. Последующий вызов pause(0.001)
or drawnow
ничего не меняет.
Как я могу заставить matlab «сбрасывать» сообщения в командное окно?
#include "mex.hpp"
#include "mexAdapter.hpp"
#include <thread>
#include <future>
class MexFunction : public matlab::mex::Function {
private:
std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();
public:
void print(const std::stringamp; msg)
{
matlab::data::ArrayFactory factory;
// Pass stream content to MATLAB fprintf function
matlabPtr->fevalAsync(u"fprintf", 0,
std::vector<matlab::data::Array>({ factory.createScalar(msg) }));
// matlabPtr->evalAsync(u"pause(0.001);");
}
void DisplayDateTime() {
matlab::data::ArrayFactory factory;
for (int count = 0; count < 20; count )
{
print("Loop " std::to_string(count) "n");
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
void operator()(matlab::mex::ArgumentList outputs,
matlab::mex::ArgumentList inputs) {
mexLock();
voidStdFuture = std::async(std::launch::async,
amp;MexFunction::DisplayDateTime, this);
}
};
Комментарии:
1. Мне кажется, это указывает на то, что асинхронный вызов должен выполняться после завершения работы MEX-файла. Вы запускаете свой MEX-файл вне процесса? В противном случае процесс MATLAB зависает до завершения работы MEX-файла. Может быть, вызов
drawnow
после печати помогает?2. Вы пробовали
feval
? Не уверен, но из того, что вы пишете в другом вопросе, кажется, что по сравнению со старым C API многое изменилось.3. @CrisLuengo Если вы вызовете feval из отдельного потока, matlab выйдет из строя. Если вы вызываете feval из основного потока, сообщения появляются, даже если matlab занят. И нет, drawnow ничего не меняет.
4.
fevalAsync
может записывать в предоставленный пользователем буфер потока . Итак, похоже, что вам нужно определить подкласс std::basic_streambuf , который обертывает буфер потокаstd::wcout
. MATALAB нуждается в буфере потока типаbasic_streambuf<char16_t>
, в то времяwcout
как имеет буфер потока типаbasic_streambuf<wchar_t>
. Это следует учитывать при переопределении виртуальных методов. Эти методы правильно вызывают методы буфера обернутого потока.