在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)我还想进一步并行启动一些这样的实例......
谢谢!
答案 0 :(得分:0)
在紧密循环中打开文件可能不会让操作系统考虑删除它;考虑如果您在OS执行由Matlab启动的删除调用时拥有该文件。
在循环中添加睡眠或等待(至少100毫秒,越多越好)应该为操作系统提供删除文件的时间。