Неблокирующий вызов внешней программы без потери кода возврата - PullRequest
8 голосов
/ 15 июля 2011

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

Ответы [ 3 ]

8 голосов
/ 15 июля 2011

Я не уверен, что MATLAB имеет встроенную / встроенную поддержку для порождения процесса. Вы можете использовать Java из MATLAB для его реализации.

Например,

>> 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
2 голосов
/ 15 июля 2011

Если у вас есть программный доступ к другой программе, то самый простой способ обойти это - просто сохранить в другой программе результаты или заметки о ходе выполнения в текстовый файл и прочитать их в Matlab.* Если вы не можете сделать это таким образом, вы можете заглянуть в параллельные вычислительные инструменты .Вы можете использовать один поток, чтобы запустить процесс, и другой поток, чтобы контролировать его.У меня было несколько вопросов о том, как использовать панель инструментов;опробуйте их примеры и опубликуйте будущие вопросы здесь.Удачи!

0 голосов
/ 02 сентября 2011

MATLAB может выполнять вызовы системного уровня. Вместо того чтобы тратить $ на «Parallel Computing Toolbox», вызывайте matlab из себя.

моя машина имеет 4 ядра, каждое с 2 потоками. Когда я усердно работаю с MATLAB, я использую только 12,5% процессора. Поэтому я начал использовать более одного экземпляра MATLAB одновременно.

ех. (на Windows-машине с несколькими ядрами или гиперпоточностью)

system('matlab -r "for i=1:1000000000,disp(num2str(i));end;" &'); for i=1:1000000000,disp(num2str(i));end;

все в одной строке в командной строке MATLAB, это открывает второй экземпляр, и оба считают до миллиарда.

Вместо аргумента for i=1:1000000000,disp(num2str(i));end; дайте MATLAB вызов функции, например disp('dsfljkhjhkalkhjdfsahjkldahjkdfshjk'). Это не позволяет легко получать возвращаемые переменные, но хорошим решением может быть сохранение данных в файлах .mat.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...