无阻塞调用外部程序而不会丢失返回代码

Atz*_*nik 8 matlab

在Matlab中启动外部程序(简称为"EX")时,我可以这样做

[status, result] = system('EX.exe');
Run Code Online (Sandbox Code Playgroud)

哪个阻止直到EX返回,或者像这样

[status, result] = system('start EX.exe');
Run Code Online (Sandbox Code Playgroud)

它立即返回Matlab但无法获取EX的返回码.

一旦完成,仍然可以在Matlab中使用EX的返回代码.这将是调用Matlab脚本注意EX可能遇到的任何问题的最简单方法.另一方面,我希望Matlab在EX运行时执行其他操作,例如显示有关进度的信息.因此,呼叫需要是非阻塞的.

我尝试通过启动EX来解决这个明显的冲突,如上面第一个例子中所述.为了能够在EX忙时运行一些其他代码(显示进度信息),我将这段代码放入一个函数中,并使用一个带有小StartDelay的计时器调用它.

不幸的是,这并没有提供真正的多线程(如果没有Parallel Computing Toolbox,Matlab似乎无法实现),即如果计时器回调中的代码运行时间超过EX,则执行再次阻塞,直到计时器回调返回.更糟糕的是:由于我不知道EX会运行多长时间,因此定时器回调必须无休止地运行,直到它被停止或传递一些告诉它停止的标志.我尝试使用全局变量,甚至将此标志存储在应用程序数据中,如下所示:

setappdata(0, 'running', 1);

tim = timer(...
    'StartDelay', 2, ...
    'TimerFcn',   'while getappdata(0, ''running''), fprintf(''timer running ...\n''); pause(1); end' ...
);

fprintf('Starting timer.\n');
start(tim);

fprintf('Calling external program ...\n');
[s,r] = system('EX.exe');
fprintf('External program returned %d.\n', s); % <-- This is never reached.

setappdata(0, 'running', 0);

fprintf('Stopping timer.\n');
stop(tim);
delete(tim);
Run Code Online (Sandbox Code Playgroud)

调用system()之后的代码似乎永远不会被执行,并且定时器回调会永远运行...有没有其他方法可以让它工作或者它真的是系统的返回值还是非阻塞调用?

And*_*ron 8

我不确定MATLAB是否有生成进程的本机/内置支持.但是,您可以使用MATLAB中的Java来实现它.

例如,

>> runtime = java.lang.Runtime.getRuntime();
>> process = runtime.exec('program arg1 arg2');
>> ...
>>
>>   % when you want to collect results.
>> process.waitFor(); % block until program returns.
>> process.exitValue(); % fetch process return code.
>>
>>   % or, if you need to abandon the work,
>> process.destroy(); % violently kill process
Run Code Online (Sandbox Code Playgroud)

  • @Atze:我猜MATLAB有自己的Java运行时.AFAIK,它需要Java来运行解释器,许多核心函数都是用MATLAB代码编写的.很高兴知道它有效,我将需要在不久的将来做同样的事情! (2认同)