在 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) 我还想同时启动几个这样的实例...
谢谢!
最佳答案
在紧密循环中打开文件可能不会给操作系统考虑删除它的机会;考虑如果您拥有该文件,而操作系统执行由 Matlab 发起的删除调用。
在循环中添加 sleep 或等待(至少 100 毫秒,越长越好)应该为操作系统删除文件留出时间。
关于c++ - 从 C++ 启动 matlab 脚本并等待结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29141620/