从C++启动matlab脚本并等待结果

Launching matlab script from C++ and wait for result

本文关键字:等待 结果 脚本 matlab C++ 启动      更新时间:2023-10-16

在StackOverflow上发表了几篇文章之后,我将通过运行来启动一个matlab脚本

matlab.exe -nodisplay -nosplash -nodesktop -r "run('script.m'); exit;"

实际上,由于这个脚本需要参数,我还将它们设置为全局变量。它运行良好。但是,我多次运行这个脚本,传递不同的参数,并且我希望在启动下一个实例之前完成脚本的一个实例。

所以,在我的C++代码中,我正在做:

        SHELLEXECUTEINFO ShExecInfo = { 0 };
        ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
        ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
        ShExecInfo.hwnd = NULL;
        ShExecInfo.lpVerb = NULL;
        ShExecInfo.lpFile = _T("matlab.exe");
        ShExecInfo.lpParameters = _T("-nodisplay -nosplash -nodesktop -r "file1='tmp0.png'; file2='tmp1.png'; outfile='tmpout.flo'; run('runflow.m'); exit; "");
        ShExecInfo.lpDirectory = NULL;
        ShExecInfo.nShow = SW_SHOWMINNOACTIVE;
        ShExecInfo.hInstApp = NULL;
        ShellExecuteEx(&ShExecInfo);
        WaitForSingleObject(ShExecInfo.hProcess, INFINITE);

这实际上并不需要等待脚本完成,我最终得到了数百个同时存在的matlab实例。为了避免这种情况,我只是做了一个小黑客:从matlab中删除文件tmp0.png,然后等待这个文件被删除:

        SHELLEXECUTEINFO ShExecInfo = { 0 };
        ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
        ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
        ShExecInfo.hwnd = NULL;
        ShExecInfo.lpVerb = NULL;
        ShExecInfo.lpFile = _T("matlab.exe");
        ShExecInfo.lpParameters = _T("-nodisplay -nosplash -nodesktop -r "file1='tmp0.png'; file2='tmp1.png'; outfile='tmpout.flo'; run('runflow.m'); delete('tmp0.png'); exit; "");
        ShExecInfo.lpDirectory = NULL;
        ShExecInfo.nShow = SW_SHOWMINNOACTIVE;
        ShExecInfo.hInstApp = NULL;
        ShellExecuteEx(&ShExecInfo);
        WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
        while (file_exists("tmp0.png")) ;  

其中:

bool file_exists(const char* filename) {
    std::ifstream ifile(filename);
    return ifile.good();
}

但这有时有效,有时无效。特别是,它经常陷入一个无限循环。。。。直到我手动转到windows资源管理器,右键单击文件"tmp0.png"并单击"属性",这时,它意识到文件可能已经被删除,并最终参与下一次迭代。。。

[编辑]实际上,我意识到/每次/我点击Properties,它都会启动一个新的Matlab实例,无论是否已经有实例在运行。。。

1) 为什么会发生这种情况
2) 我该如何规避这一点(我并不是特别寻找优雅的解决方案,只是一些行之有效的解决方案)
3) 我还想同时推出一些这样的例子。。。

谢谢!

在紧密循环中打开一个文件可能不会给操作系统考虑删除它的机会;考虑在操作系统执行由Matlab启动的删除调用时是否拥有该文件。

在循环中添加睡眠或等待(至少100ms,越多越好)应该会给操作系统删除文件的时间。