Семафоры и замки в MATLAB - PullRequest
13 голосов
/ 20 июня 2011

Я работаю над проектом MATLAB, где мне бы хотелось, чтобы два экземпляра MATLAB работали параллельно и обменивались данными. Я назову эти случаи MAT_1 и MAT_2. В частности, архитектура системы:

  1. MAT_1 обрабатывает изображения последовательно, считывая их одно за другим, используя imread, и выводит результат для каждого изображения, используя imwrite.
  2. MAT_2 читает изображения, выведенные с помощью MAT_1, используя imread и выводит результат в другое место.

Одна из проблем, которую, я думаю, мне нужно решить, состоит в том, чтобы гарантировать, что MAT_2 считывает вывод изображения MAT_1 после того, как MAT_1 полностью завершит запись в него.

Мои вопросы:

  1. Как бы вы подошли к этой проблеме? Нужно ли использовать семафоры или замки для предотвращения гонки?
  2. Предоставляет ли MATLAB какой-либо механизм для блокировки файлов? (то есть что-то похожее на flock, но предоставляется непосредственно MATLAB и работает на нескольких платформах, например, Windows & Linux). Если нет, знаете ли вы какую-либо стороннюю библиотеку, которую я могу использовать для создания этого механизма в MATLAB?

РЕДАКТИРОВАТЬ:

  • Как указывает @yoda ниже, Parallel Computing Toolbox (PCT) позволяет блокировать вызовы между работниками MATLAB, и это здорово. Тем не менее, я особенно заинтересован в решениях, которые не требуют PCT.
  • Почему мне требуется MAT_1 и MAT_2 для работы в параллельных потоках?:

    Обработка, выполняемая в MAT_2, в среднем медленнее (и более подвержена сбоям), чем MAT_1, а вывод MAT_1 подает другие программы и процессы (включая проверку человеком), которым не нужно ждать MAT_2 делать свою работу.

Ответы:

  • Решение, которое допускает реализацию семафоров, но не полагается на PCT, см. В ответе Джонаса ниже
  • Другие подходы к проблеме см. В ответе Йоды ниже

Ответы [ 6 ]

7 голосов
/ 05 апреля 2014

Я бы подошел к этому с помощью семафоров;по моему опыту, PCT неоправданно медленно синхронизируется.

dfacto (другой ответ) имеет отличную реализацию семафоров для MATLAB, однако он не будет работать в MS Windows;Я улучшил эту работу так, чтобы это было.Улучшенная работа здесь: http://www.mathworks.com/matlabcentral/fileexchange/45504-semaphoreposixandwindows

Это будет лучше, чем взаимодействие с Java, .NET, PCT или блокировками файлов.При этом не используется Parallel Computing Toolbox (PCT), а функциональность семафора AFAIK в любом случае отсутствует в PCT (удивительно, что они его не использовали!).Можно использовать PCT для синхронизации, но все, что я пробовал, было неоправданно медленным.

Чтобы установить эту высокопроизводительную библиотеку семафоров в MATLAB, запустите ее в интерпретаторе MATLAB: mex -O -vsemaphore.c

Вам потребуется установленный компилятор C ++ для компиляции semaphore.c в двоичный MEX-файл.Этот MEX-файл затем вызывается из вашего кода MATLAB, как показано в примере ниже.

Пример использования:

function Example()
    semkey=1234;
    semaphore('create',semkey,1);
    funList = {@fun,@fun,@fun};
    parfor i=1:length(funList)
        funList{i}(semkey);
    end
end
function fun(semkey)
    semaphore('wait',semkey)
    disp('hey');
    semaphore('post',semkey)
end
4 голосов
/ 20 июня 2011

Лично я бы использовал для этого набор инструментов параллельной обработки.

Насколько я знаю, в Matlab нет простого способа обеспечить блокировку файлов в масштабе всей системы. Однако, чтобы гарантировать, что Matlab # 2 считывает вывод Matlab # 1 только после того, как файл завершил запись, я предлагаю после записи, например, файла results_1.mat, Matlab # 1 записывает второй файл results_1.finished, пустой текстовый файл. Поскольку второй файл записывается после первого, его существование сигнализирует, что файл результатов был записан. Таким образом, вы можете искать файлы с расширением finished, т.е. dir('*.finished'), и использовать fileparts, чтобы получить имя файла .mat, который вы хотите загрузить с Matlab # 2.

2 голосов
/ 10 августа 2011

Я не уверен, что вы ищете решение только для matlab, но я только что представил обертку семафора для использования в Matlab.Он работает как общий семафор, но в основном был разработан с учетом sharedmatrix .

Как только Mathworks примет представление, я обновлю ссылку на блог моей исследовательской группы.

Обратите внимание, что этот mex-файл является оберткой для функциональности семафора POSIX.Как таковая, она будет работать в Linux, Unix, MacOS, но не будет работать в Windows.Может работать при компиляции с библиотеками cygwin.

1 голос
/ 21 июня 2011

РЕДАКТИРОВАНИЕ:

После просмотра вашего редактирования простое решение, не включающее использование каких-либо наборов инструментов, выглядит следующим образом:

Поскольку MAT_2 намного медленнее, чем MAT_1, начните MAT_2 с задержкой.то есть, запустите его, когда MAT_1 закончит обработку, скажем, 5 изображений или около того.Если вы сделаете это, MAT_2 никогда не догонит MAT_1 и, следовательно, никогда не будет в ситуации, когда ему придется «ждать» изображения из MAT_1.


. Явсе еще неясно несколько вещей из вашего вопроса:

  1. Вы говорите, что MAT_1 обрабатывает изображения последовательно, но это должно ?Другими словами, имеет значение порядок, в котором они обрабатываются?
  2. Вы говорите, MAT_2 читает вывод из MAT_1 ... Должно ли это быть в том порядке, в котором MAT_1 заканчивается или можетэто какой-нибудь заказ?
  3. Вы говорите, MAT_2 читает изображение, используя imread, и выводит его где-то еще.Есть ли причина, по которой задача не может быть объединена в MAT_1?

В любом случае вы можете реализовать некоторую форму блокировки выполнения с помощью набора инструментов параллельных вычислений;но вместо использования parfor циклов (это то, что используется большинством людей), вам придется создать распределенное задание ( пример ).

Важно отметить, что каждыйработник (лаборатория) имеет labindex, и вы можете использовать labSend для отправки данных от работника 1 (эквивалент MAT_1) работнику 2 (эквивалент * 1046)*), который затем получает его, используя labReceive.Из документации по labReceive:

Эта функция блокирует выполнение в лаборатории до тех пор, пока в отправляющей лаборатории не произойдет соответствующий вызов labSend.

, что довольно многовы хотели сделать с MAT_1 и MAT_2.

Еще один способ сделать это - создать еще одного рабочего в текущем сеансе, но назначить ему только задачи, выполняемые MAT_1.Затем вы устанавливаете свойство FinishedFcn для задач для выполнения набора функций, выполняемых MAT_2, но я бы не рекомендовал его, так как не думаю, что это было намерением для FinishedFcnи я не знаю, сломается ли он в некоторых случаях.

1 голос
/ 20 июня 2011

Я не думаю, что есть надежный способ, кроме использования блокировок, специфичных для ОС. Один из подходов может заключаться в том, чтобы сделать MAT_1:

imwrite(fileName);
movefile(fileName, completedFileName);

И у MAT_2 только процесс завершен FileName.

0 голосов
/ 20 июня 2011

Я бы также порекомендовал взглянуть на панель инструментов параллельной обработки, где-то должна быть нужная вам функциональность. Я думаю, что это чище, чем пытаться синхронизировать два экземпляра MATLAB (если только вы не вынуждены использовать два экземпляра).

В странном случае, когда такой вещи нет, вы также можете взглянуть на разные среды, чтобы реализовать то, что вы хотите. Это может быть чем-то вроде обходного пути, но вы всегда можете связать свой код MATLAB с другими языками (например, Java, .NET, C, ...) и использовать функциональность, к которой вы привыкли. С Java вы совершенно уверены, что ваше решение не зависит от платформы, .NET работает только в Windows (по крайней мере, в сочетании с MATLAB).

...