Неблокирующий вызов внешней программы без потери кода возврата

При запуске внешней программы (назовем ее "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 (), кажется, никогда не выполняется, а обратный вызов таймера работает вечно ... Есть ли другой способ получить это работает, или это действительно либо возвращаемое системой значение, либо неблокирующий вызов?

8
задан Atze Kaputtnik 15 July 2011 в 14:41
поделиться