Порты Erlang и потокобезопасность

Я хочу вызвать функцию C из процесса Erlang через порт Erlang, как описано здесь:

http://www.erlang.org/doc/tutorial/c_port.html

В производственной среде мне потребуется несколько процессов Erlang, параллельно вызывающих функцию C, каждый с другим набором аргументов.

Мой вопрос: будет ли это потокобезопасным на уровне функции C?

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

Так что это звучит как потокобезопасность на уровне C, но я хотел бы быть уверен на 100%.

ТИА


person Justin    schedule 22.04.2015    source источник


Ответы (2)


Это может зависеть от вашей реализации, но с портами ответ почти определенно «да» по причине, которую вы упомянули. Если бы вы использовали NIF и совместно используемую память внутри NIF, у вас были бы некоторые опасения по поводу безопасности потоков.

Однако с портами «процесс управления» действует как уровень сериализации (как в последовательном порядке), что означает, что запросы обрабатываются один за другим, а не все сразу. Более того, я считаю (но не знаю наверняка), что использование портов протокола связи также требует этого последовательного выполнения.

person Soup d'Campbells    schedule 22.04.2015

Порт — это программа, которая взаимодействует со стороной Erlang, используя стандартный ввод-вывод. Нужна ли вам безопасность потоков или нет, зависит от протокола связи, который вы реализуете.

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

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

  1. прочитать команду из стандартного ввода
  2. обработать эту команду
  3. записать результат в стандартный вывод
  4. go to 1

Параллелизм обрабатывается на стороне erlang, так как все входящие команды будут накапливаться в папке «Входящие» порта, пока порт обрабатывает одну за другой.

Для последнего вам понадобится механизм для асинхронной обработки входных сообщений git remote add origin [email protected]:samuelrivas/dfberl.git, здесь для простоты я буду использовать потоки:

Основной цикл:

  1. прочитать команду из стандартного ввода
  2. создать поток для его обработки
  3. go to 1

Петля нити:

  1. команда процесса
  2. записать результат в стандартный вывод

Обратите внимание, что потокам потребуется какая-то блокировка при записи в стандартный вывод, я обычно реализую эту часть как еще один поток с асинхронной очередью, в которую все остальные потоки публикуют результаты.

Во втором сценарии у вас будет параллелизм на стороне C, поэтому вам нужно позаботиться о безопасности потоков. В первом случае сторона C не обрабатывает параллелизм, поэтому безопасность потоков здесь не вызывает беспокойства.

person Samuel Rivas    schedule 11.07.2015