When starting the external program (let's call it "EX" for brevity) from within Matlab I can either do it like this
[status, result] = system('EX.exe');
which blocks until EX returns, or like this
[status, result] = system('start EX.exe');
which returns to Matlab immediately but can't fetch EX's return code.
It would be nice to still have EX's return code available in Matlab once it is done. This would be the easiest way for the calling Matlab script to notice any problems EX might run into. On the other hand, I would like Matlab to do other stuff while EX is running, e.g. displaying information on progress. So, the call needs to be non-blocking.
I tried to work around this obvious conflict by starting EX as described in the first example above. To be able to run some other code (displaying progress information) while EX is busy, I put this code into a function and called that by using a timer with a small StartDelay.
Unfortunately this does not provide real multithreading (something that Matlab seems to be incapable of without Parallel Computing Toolbox), i.e. if the code in the timer callback runs longer than EX, execution again blocks until the timer callback returns. Even worse: Since I don't know how long EX will run, the timer callback must run endlessly until it is either stopped or passed some flag that tells it to stop. I tried with global variables or even storing this flag in application data like this:
setappdata(0, 'running', 1);
tim开发者_如何学Python = 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);
The code following the call to system() never seems to be executed and the timer callback runs forever ... Is there any other way I can get this to work or is it really either system's return value OR non-blocking call?
I'm not sure MATLAB has native/built-in support for spawning a process. You can use Java from MATLAB to implement it, though.
For instance,
>> 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
If you have programmatic access to the other program, then the easiest way to get around this by far is to simply have the other program save results or progress notes to a textfile, and have matlab read that.
If you can't to do it that way, you may want to look into the parallel computing toolbox. You can use one thread to start the process and another thread to monitor it. I had a few questions myself on how to use the toolbox; try out their examples and post future questions here. Good luck!
MATLAB can make system level calls. Instead of spending $ on the "Parallel Computing Toolbox", call matlab from itself.
my machine has 4 cores, each with 2 threads. When I work MATLAB hard, I only use 12.5% of the processor. So I've begun using more than one instance of MATLAB at a time.
ex. (on a windows machine with multiple cores, or hyper-threading)
system('matlab -r "for i=1:1000000000,disp(num2str(i));end;" &'); for i=1:1000000000,disp(num2str(i));end;
all in one line at the MATLAB command prompt, this opens a second instance, and both count to a billion.
Instead of the for i=1:1000000000,disp(num2str(i));end;
argument, give MATLAB a function call, like disp('dsfljkhjhkalkhjdfsahjkldahjkdfshjk')
. This doesn't allow you to get return variables easily, but a good workaround might be saving things in .mat files.
精彩评论