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

时间:2015-03-19 10:04:05

标签: c++ windows matlab launching-application

在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'然后单击“属性”,此时,它会意识到文件可能已被删除,最后会进入下一次迭代......

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

1)为什么会发生这种情况? 2)我如何规避(我不是特别寻找优雅的解决方案;只是有效的方法) 3)我还想进一步并行启动一些这样的实例......

谢谢!

1 个答案:

答案 0 :(得分:0)

在紧密循环中打开文件可能不会让操作系统考虑删除它;考虑如果您在OS执行由Matlab启动的删除调用时拥有该文件。

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