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

Launching matlab script from C++ and wait for result

在 Whosebug 上的几篇文章之后,我通过 运行

启动了一个 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) 我还想同时启动几个这样的实例...

谢谢!

在紧密循环中打开文件可能不会给 OS 考虑删除它的机会;考虑如果您拥有该文件,而 OS 执行由 Matlab 发起的删除调用。

在循环中添加睡眠或等待(至少 100 毫秒,越长越好)应该为操作系统删除文件提供时间。