2009-05-29 4 views
2

Я планирую использовать именованные каналы Unix (mkfifo) для простого обмена сообщениями с несколькими процессами. Сообщение будет всего лишь одной строкой текста.Препятствия для обмена сообщениями FIFO (named pipe)

Не могли бы вы отговорить меня от этого? Какие препятствия я должен ожидать?

Я заметил эти ограничения:

  1. Отправитель не может продолжаться, пока сообщение не будет получено.
  2. Приемник заблокирован до тех пор, пока не появится некоторая информация. Неблокирующий IO был бы необходим , когда нам нужно остановить чтение. Например, может потребоваться другой поток.
  3. Приемник может получать много сообщений в одном чтении. Они должны быть обработаны перед отъездом.
  4. Максимальная длина атомного сообщения ограничена 4096 байтами. Это ограничение PIPE_BUF для Linux (см. Man 7 pipe).

Я реализую обмен сообщениями в Python. Но препятствия вообще сохраняются.

+0

Сколько процессов вы ожидаете использовать в то же время? Если у вас более одного читателя, письменное сообщение будет видно только одному из читателей AFAIR. (Не на 100% уверены в этом) – rodion

+0

@rodion - Да, он предназначен для просмотра сообщения только в одном читателе. FIFO работает именно так. –

+0

Почему проблема с блокировкой? Я вижу неблокирующую запись. Я не вижу смысла неблокирующего чтения, когда вы ждете работы. –

ответ

5
  1. Отсутствие переносимости - это в основном вещь Unix. Розетки более портативные.
  2. Сложнее масштабировать до нескольких систем (другие гнезда +)
  3. С другой стороны, я считаю, что трубы быстрее, чем сокеты для процессов на одном компьютере (без коммуникационных издержек).

Как ваши ограничения,

  1. Вы можете «select» на трубах, чтобы сделать без блокировки чтения.
  2. Я обычно (в perl) распечатываю свои сообщения на трубах, разделенных «\ n», и читаю строку из них, чтобы получить по одному сообщению за раз.
  3. Будьте осторожны с атомной длиной.

Я нахожу perlipc, чтобы быть хорошим обсуждением между различными вариантами, хотя он имеет специфический код perl.

+0

Readline() в приемнике не спасет вас от хранения нескольких сообщений во внутреннем буфере. Перед тем, как уйти, они все равно должны быть обработаны. –

3

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

Дальнейшие ограничения FIFOs:

  • только один клиент одновременно.
  • После того, как клиент закрывает FIFO, серверу необходимо повторно открыть его конечную точку.
  • Однонаправленный.

Вместо этого я бы использовал UNIX domain sockets, которые не имеют ни одного из вышеуказанных ограничений.

В качестве дополнительного преимущества, если вы хотите масштабировать его для связи между несколькими машинами, это практически не имеет никаких изменений.Например, просто зайдите на страницу документации Python по адресу socket и замените socket.AF_INET на socket.AF_UNIX, (HOST, PORT) с filename, а его просто работает.

SOCK_STREAM даст вам потоковое поведение; то есть два отправления могут быть объединены в один прием или наоборот. AF_UNIX также поддерживает SOCK_DGRAM: датаграммы должны быть отправлены и прочитаны как единое целое или нет. (Аналогично, AF_INET + SOCK_STREAM = TCP, AF_INET + SOCK_DGRAM = UDP.)

+0

Что значит «Только один клиент за раз»? У меня могло быть несколько писателей и читателей на FIFO. –

+0

Вам нужно открыть FIFO для чтения несколько раз. Прием новых соединений в одном и том же гнезде для прослушивания намного чище. – ephemient

+0

Просто FYI, по-видимому, на некоторых платформах Unix (Solaris) FIFO являются двунаправленными .. но ваша точка действительна. Вместо этого используйте сокеты домена unix. – nosatalian

Смежные вопросы