При запуске внешней программы (для краткости будем называть ее «EX») из Matlab я могу сделать это так
[status, result] = system('EX.exe');
, которая блокируется до возврата EX, или вот так
[status, result] = system('start EX.exe');
, который немедленно возвращается в Matlab, но не может получить код возврата EX.
Было бы хорошо иметь код возврата EX, доступный в Matlab, как только это будет сделано.Для вызывающего скрипта Matlab это был бы самый простой способ заметить любые проблемы, с которыми может столкнуться EX.С другой стороны, я бы хотел, чтобы Matlab делал другие вещи во время работы EX, например, отображал информацию о прогрессе.Итак, вызов должен быть неблокирующим.
Я попытался обойти этот очевидный конфликт, запустив EX, как описано в первом примере выше.Чтобы иметь возможность запускать какой-то другой код (отображающий информацию о ходе выполнения), пока EX занят, я поместил этот код в функцию и вызвал ее, используя таймер с небольшим StartDelay.
К сожалению, это не обеспечивает реальной многопоточности(что-то, что Matlab кажется неспособным без Parallel Computing Toolbox), т.е. если код в обратном вызове таймера выполняется дольше, чем 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);
Код, следующий за вызовом system (), кажется, никогда не выполняется, и обратный вызов таймера выполняется вечно ...каким-либо другим способом я могу заставить это работать или это действительно возвращаемое значение системы ИЛИ неблокирующий вызов?