Обнаружение процессов Matlab из Matlab - PullRequest
8 голосов
/ 13 мая 2009

Есть ли способ определить, сколько процессов matlab выполняется на компьютере из программы matlab?

Я бы хотел, чтобы запущено ровно n процессов matlab. Если у меня их слишком мало, я хочу создать их, а если у меня их много, я хочу убить их. Конечно, вы можете сделать это вручную, но я бы предпочел, чтобы это было автоматически, если это возможно и не сложно для реализации.

Дополнительная информация: В настоящее время я использую windowsx64 (vista), но мне интересны и другие платформы.

Ответы [ 6 ]

11 голосов
/ 13 мая 2009

Если вы работаете в Windows, вы можете сделать это:

[s,w] = dos( 'tasklist' );
numMatlabs = length( regexp( w, '(^|\n)MATLAB.exe' ) )
5 голосов
/ 14 мая 2009

Вот еще один подход: вы можете использовать COM «Сервер автоматизации» Matlab для запуска рабочих и управления ими из центрального процесса Matlab.

function out = start_workers(n)
myDir = pwd;
for i=1:n
    out{i} = actxserver( 'matlab.application.single' );
    out{i}.Execute(sprintf('cd(''%s'')', myDir));
end

Затем вы можете использовать Execute (), чтобы они запускали работу. Вы можете использовать трюк с таймером для получения асинхронного выполнения.

function out = evalasync(str)
%EVALASYNC Asynchronous version of eval (kind of)
%
% evalasync(str)  % evals code in str
% evalasync()     % gets results of previous call

persistent results status exception

if nargin == 0
    out = {status results exception}; % GetWorkspaceData doesn't like structs
    assignin('base', 'EVALASYNC_RESULTS', out); % HACK for Automation
    return
end

status = 'waiting';
    function wrapper(varargin)
        status = 'running';
        try
            results = eval(str);
            status = 'ok';
        catch err
            status = 'error';
            exception = err;
        end
    end

t = timer('Tag','evalasync', 'TimerFcn',@wrapper);
startat(t, now + (.2 / (60*60*24)));

end

Тогда

w = start_workers(3);
w{1}.Execute('evalasync(''my_workload(1)'')');
w{2}.Execute('evalasync(''my_workload(2)'')');

К сожалению, вы застряли с однопоточностью в рабочих, поэтому если вы снова вызовете evalasync () для проверки результатов, он заблокируется. Таким образом, вы хотите контролировать их прогресс через файлы на диске. Таким образом, это не может быть большой победой.

3 голосов
/ 13 мая 2009

на Linux

!ps -ef |grep "/usr/local/matlab78/bin/glnxa64/MATLAB"|wc -l

сработает (замените путь на свой собственный и вычтите 1 для процесса grep)

(или для встраивания в функцию используйте

[tmp, result] = system('ps -ef |grep "/usr/local/matlab78/bin/glnxa64/MATLAB"|wc -l');
str2double(result) - 1

также вы можете использовать

>>computer
ans = GLNXA64

чтобы узнать, какую архитектуру системы (win / linux / etc) программа выполняет в данный момент на

2 голосов
/ 13 мая 2009

Что касается определения количества процессов MATLAB, которые в настоящее время выполняются на вашем компьютере, я бы, вероятно, согласился с ответом, который Эдрик дал . Оттуда вы должны либо остановить некоторые из них, либо начать новые. Вот некоторый код (с использованием метода Edrics), который будет определять количество процессов MATLAB, открывать новые и немедленно запускать в них код. Я все еще смотрю на процесс, убивающий процесс ...

[s,w] = dos('tasklist');
nProcesses = numel(regexp(w,'(^|\n)MATLAB.exe'));
for n = 1:(3-nProcesses),  % Starts new processes if there are less than 3
  dos('MATLAB R2009a -nosplash -r why &');  % Starts a process and runs the
                                            %   built-in function "why.m"
end

Если у вас запущен 1 процесс, этот код запустится еще 2, а затем вернет управление исходному процессу MATLAB (из-за "&" в вызове функции DOS ). Когда он запускает каждый из них, он автоматически вызывает встроенную функцию MATLAB WHY (из-за «-r почему» в вызове DOS), в результате чего в каждом новом окне появляется следующий текст:

Лысый и не слишком лысый и не слишком умный хомяк подчинился испуганному и не слишком испуганному хомяку.

Заменив «почему» в вызове DOS на любой код / ​​m-файл, который вы хотите запустить, вы можете создавать новые процессы, которые мгновенно начинают обрабатывать числа.


Использование панели инструментов параллельных вычислений:

(Это старая версия моего ответа, который я оставляю здесь на случай, если кто-то посчитает его полезным)

Если вы используете Parallel Computing Toolbox для создания пула рабочих MATLAB, вам может понадобиться функция MATLABPOOL . Вот несколько способов его использования:

>> poolSize = matlabpool('size')  % Check the current pool size

poolSize =

     0

>> matlabpool('open',2);  % Open a pool of 2 workers
Starting matlabpool using the 'local' configuration ... connected to 2 labs.
>> poolSize = matlabpool('size')  % Check the pool size again

poolSize =

     2

>> matlabpool('close');  % Close the pool of workers
Sending a stop signal to all the labs ... stopped.
1 голос
/ 15 декабря 2010

Используя Windows TASKLIST, вы также можете получить PID конкретной выполняемой задачи, используя заголовок окна в качестве фильтра. Это особенно полезно, если у вас запущено несколько процессов Matlab, название которых вы изменили.

Изменение заголовка главного окна Matlab выполняется с помощью следующей функции (changeWindowTitle.m):

function changeWindowTitle(str)

% first get all of the Java frames present in the current JVM
frms = java.awt.Frame.getFrames();

% now, lets look through those frames for one that seems like it

root = [];
for m = 1:length(frms)
    if strcmpi(get(frms(m),'Type'),'com.mathworks.mde.desk.MLMainFrame')
        root = frms(m);
        break;
    end
end
if isempty(root)
    error('Could not find my main frame')
end
set(root,'Title',str)

Если вы изменили заголовок окна Matlab на «MyMatlabWindow», используя ....

> changeWindowTitle("MyMatlabWindow");

... вы можете найти PID сеанса Matlab вне Matlab, используя:

c:\tasklist /FI "WindowTitle eq MyMatlabWindow" 

Конечно, вы можете сделать то же самое из Matlab, используя dos() system() или восклицательный знак.

Кроме того, вы можете добавить аргументы /FO CSV (для форматирования вывода в формате CSV) и /NH (для подавления вывода заголовка.

c:\tasklist /FI "WindowTitle eq MyMatlabWindow" /FO CSV /NH

Источники:

0 голосов
/ 14 мая 2009

Хотите написать какой-нибудь VBScript? Вы можете написать это, используя WMI , API-интерфейс администрирования Windows с привязками сценариев. WMI может перечислить все процессы на компьютере, включая имя образа, путь и командную строку. Ищите MATLAB.exes. WMI-объект Win32_Process также предоставляет большую часть информации, отображаемой Process Explorer , например время запуска, использование процессора и памяти.

Вы можете почти сценарий WMI изнутри самого Matlab, используя actxserver () и вызовы COM-методов, но коллекции пока работают не совсем правильно. Но вы можете написать простую VBS, чтобы выполнить запрос списка процессов WMI и написать вывод, дружественный к Matlab, а затем обработать его. Это немного больше, чем использование списка задач, но вам может пригодиться дополнительная информация, если вы спорите с кучей рабочих процессов. Например, командные строки, заголовки окон или время запуска процесса могут использоваться для разграничения работников при принятии решения о том, кого убивать.

Чтобы уничтожить их, вы можете использовать Win32_Process.Terminate или WMI для команды taskkill.

Это только для Windows. Если вы хотите сделать вещи переносимыми, вы можете установить cygwin, а затем выполнить оболочку для ps в стиле Unix и команды kill в любой ОС.

Примечание: если вы заставляете обычные приложения Windows Matlab работать как работники с "-r", используйте try / catch на самом верхнем уровне основного сценария, чтобы убедиться, что он завершится, когда закончите:

try
    do_your_work();
catch err
    warning('Got an error: %s', err.message); 
end

close force all  % prevent figures from making quit() balk
quit force

В противном случае ошибка, выдаваемая в М-коде, может всплыть на верхний уровень и привести к тому, что Matlab попадет в основной цикл GUI, ожидая ввода данных пользователем, и будет выглядеть как зависший работник.

О, и если вы убиваете процессы Matlab из Matlab, вы, вероятно, хотите избежать самоубийства. Вот функция MEX, которая позволит вам определить свой собственный pid в Windows64 или Unix; проверяйте его по пидам целевых процессов при выборе жертв. Любитель ifdefs заставит его работать на win32.

/* mygetpid.c - MEX function to get PID */
#ifdef _WIN64
#include <process.h>
#define GETPID _getpid
#else
/* assume we're on Unix */
#include <unistd.h>
#define GETPID getpid
#endif
#include "mex.h"

void mexFunction(int nlhs,       mxArray *plhs[],
                 int nrhs, const mxArray *prhs[]
                )
{
    /* ... a real function would have nargin/nargout checks here... */
    plhs[0] = mxCreateDoubleScalar((int) GETPID());
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...