Сравнение Unix/Linux IPC

Множество IPC предлагаются Unix/Linux: каналы, сокеты, разделяемая память, dbus, очереди сообщений...

Каковы наиболее подходящие приложения для каждого и как они выполняются?

Ответ 1

Unix IPC

Вот большая семерка:

  • Pipe

    Полезно только для процессов, связанных с родительским/дочерним. Вызовите pipe(2) и fork(2). Однонаправленный.

  • FIFO или named pipe

    Два несвязанных процесса могут использовать FIFO в отличие от простой трубы. Вызовите mkfifo(3). Однонаправленный.

  • Socket и Unix Domain Socket

    двунаправленный. Предназначен для сетевого общения, но может использоваться и локально. Может использоваться для разных протоколов. Там нет границ сообщений для TCP. Вызовите socket(2).

  • Message Queue

    ОС поддерживает дискретное сообщение. См. sys/msg.h.

  • Signal

    Сигнал отправляет целое число в другой процесс. Не мешает хорошо с несколькими потоками. Вызовите kill(2).

  • Semaphore

    Механизм синхронизации для нескольких процессов или потоков, похожих на очередь людей, ожидающих ванную. См. sys/sem.h.

  • Общая память

    Сделайте свой собственный concurrency элемент управления. Вызовите shmget(2).

Проблема с сообщением о границах

Одним из определяющих факторов при выборе одного метода над другим является проблема границы сообщения. Вы можете ожидать, что "сообщения" будут дискретными друг от друга, но это не для потоков байтов, таких как TCP или Pipe.

Рассмотрим пару эхо-клиента и сервера. Клиент отправляет строку, сервер ее получает и отправляет обратно. Предположим, что клиент отправляет "Hello", "Hello" и "Как насчет ответа?".

В протоколах байтового потока сервер может получать как "Ад", "oHelloHow", так и "об ответе?"; или более реалистично "HelloHelloHow об ответе?". Сервер не знает, где находится граница сообщения.

Старый трюк заключается в том, чтобы ограничить длину сообщения CHAR_MAX или UINT_MAX и согласиться на отправку длины сообщения сначала в char или uint. Итак, если вы находитесь на стороне приема, вам сначала нужно прочитать длину сообщения. Это также подразумевает, что только один поток должен делать чтение сообщения за раз.

С дискретными протоколами, такими как UDP или очереди сообщений, вам не нужно беспокоиться об этой проблеме, но программные потоки байтов легче справляться, потому что они ведут себя как файлы и stdin/out.

Ответ 2

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

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

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

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

Ответ 3

Вот веб-страница с простым эталоном: https://sites.google.com/site/rikkus/sysv-ipc-vs-unix-pipes-vs-unix-sockets

Насколько я могу судить, каждый имеет свои преимущества:

  • Входы/выходы для труб являются самыми быстрыми, но для взаимодействия между ними требуется взаимодействие между родителями и дочерними элементами.
  • Sysv IPC имеет определенную границу сообщений и может локально связывать разрозненные процессы.
  • Сокеты UNIX могут подключаться к разным процессам локально и имеют более высокую пропускную способность, но нет встроенных границ сообщений.
  • Сокеты TCP/IP могут подключать любые процессы даже по сети, но имеют более высокие накладные расходы и никаких неотъемлемых границ сообщений.

Ответ 4

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

В общей памяти не нужно использовать ужасные функции общей памяти sysv - гораздо более элегантно использовать mmap() (mmap файл на tmpfs/dev/shm, если вы хотите, чтобы он был назван; mmap/dev/zero если вы хотите, чтобы не выполнялись процессы exec'd, чтобы наследовать его анонимно). Сказав это, он по-прежнему оставляет ваши процессы с некоторой необходимостью синхронизации, чтобы избежать проблем - обычно, используя некоторые из других механизмов IPC для синхронизации доступа к области общей памяти.