




Вот большая семерка:
Полезно только среди процессов, связанных как родитель / потомок. Вызовите pipe(2) и fork(2). Однонаправленный.
ФИФО или именованный канал
Два несвязанных процесса могут использовать FIFO в отличие от обычного канала. Позвоните mkfifo(3). Однонаправленный.
Двунаправленный. Предназначен для сетевого взаимодействия, но может использоваться и локально. Может использоваться для разных протоколов. Для TCP нет границ сообщений. Позвоните socket(2).
ОС поддерживает дискретное сообщение. См. sys / msg.h.
Сигнал отправляет целое число другому процессу. Плохо сочетается с многопоточностью. Позвоните kill(2).
Механизм синхронизации для нескольких процессов или потоков, похожий на очередь людей, ожидающих ванной. См. sys / sem.h.
Сделайте свой собственный контроль параллелизма. Позвоните shmget(2).
Одним из определяющих факторов при выборе одного метода перед другим является проблема границ сообщения. Вы можете ожидать, что «сообщения» будут отделены друг от друга, но это не для байтовых потоков, таких как TCP или Pipe.
Рассмотрим пару эхо-клиента и сервера. Клиент отправляет строку, сервер получает ее и отправляет обратно. Предположим, клиент отправляет «Привет», «Привет» и «Как насчет ответа?».
С протоколами потока байтов сервер может получать как «Hell», «oHelloHow» и «about an answer?»; или более реалистично «Привет, привет, как насчет ответа?». Сервер не знает, где находится граница сообщения.
Старый трюк состоит в том, чтобы ограничить длину сообщения до CHAR_MAX или UINT_MAX и согласиться сначала отправить длину сообщения в char или uint. Итак, если вы находитесь на принимающей стороне, вам нужно сначала прочитать длину сообщения. Это также означает, что только один поток должен выполнять чтение сообщения за раз.
С дискретными протоколами, такими как UDP или очереди сообщений, вам не нужно беспокоиться об этой проблеме, но с программными потоками байтов легче справиться, потому что они ведут себя как файлы и stdin / out.
Я предполагаю, что вы могли бы включить туда семафоры, но я считаю это скорее инструментом параллелизма, чем инструментом межпроцессного взаимодействия.
кстати, вы можете отправлять файловые дескрипторы через сокет домена Unix [linux.die.net/man/7/unix]
Не забывайте о popen (3), чтобы упростить себе жизнь при использовании каналов.
Одна небольшая проблема: pipe (2) также может использоваться в дочерних процессах - например, оболочка является родительской для всех процессов в конвейере.
Обратите внимание, что у вас могут быть сокеты домена unix, ориентированные на сообщения. В отличие от интернет-они надежны.
Есть ли эталонный тест или качественное сравнение производительности этих подходов?
этот ответ так бесполезен. вы просто перечислили их, а не сравнивали их эффективность
Но использование именованного канала может быть очень опасным, если поток байтов действительно быстрый. Некоторые данные могут быть потеряны, если входные данные поступают слишком быстро. Я испытал это.
Совместно используемая память может быть наиболее эффективной, поскольку вы строите на ней свою собственную схему связи, но она требует большой осторожности и синхронизации. Также доступны решения для распределения разделяемой памяти на другие машины.
Розетки в наши дни являются самыми портативными, но они требуют больше накладных расходов, чем трубы. Возможность прозрачно использовать сокеты локально или по сети - отличный бонус.
Очереди сообщений и сигналы могут быть полезны для приложений жесткого реального времени, но они не так гибки.
Эти методы были естественным образом созданы для связи между процессами, и использование нескольких потоков внутри процесса может усложнить ситуацию, особенно с сигналами.
По моему опыту, именованные каналы могут быть такими же быстрыми и безопасными, чем любой другой метод.
Стоит отметить, что многие библиотеки реализуют один тип вещей поверх другого.
Общая память не нуждается в использовании ужасных функций общей памяти sysv - гораздо элегантнее использовать mmap () (mmap файл в tmpfs / dev / shm, если вы хотите, чтобы он был назван; mmap / dev / zero, если хотите разветвленные процессы, которые не выполняются, чтобы унаследовать его анонимно). Тем не менее, это по-прежнему оставляет вашим процессам некоторую потребность в синхронизации, чтобы избежать проблем - обычно с использованием некоторых других механизмов IPC для синхронизации доступа к общей области памяти.
Я никогда раньше не слышал о mmaping / dev / zero. Гениально! Вы упоминаете, что им можно делиться только с детьми, но можете ли вы отправить дескриптор файла, который вы используете, в несвязанный процесс, используя cmsg / SCM_RIGHTS через сокет домена unix, и получить там общее сопоставление? Или это унаследованное вами отображение, а не дескриптор файла? Даже если это работает, вам все равно нужен сокет где-нибудь в файловой системе для этого, поэтому даже если отображение анонимно, сокет, используемый для его настройки, не будет. Ага. IPC - это сложно. Пойдем по магазинам!
mmaping / dev / zero фактически используется некоторыми видами выделения памяти. Но преимущество в том, что если вы используете MAP_SHARED, он будет совместно использоваться вашими дочерними процессами fork () ed (обычная память логически копируется). Можете ли вы поделиться этим с другим процессом? Я так не думаю. Я подозреваю, что нужно использовать вызов mmap (), а не файловый дескриптор.
Вот веб-страница с простым тестом: https://sites.google.com/site/rikkus/sysv-ipc-vs-unix-pipes-vs-unix-sockets
Насколько я могу судить, у каждого из них есть свои преимущества:
Может быть, это. sites.google.com/site/rikkus/…
как сравнить dbus с другими?
DBUS использует один или несколько из этих механизмов. Уже давно ведется работа над собственным механизмом IPC под названием DBUS1 (или KDBUS ...), но он до сих пор не интегрирован в основное ядро.
Ссылка sites.google.com/site/rikkus/… мертва
dbus реализован поверх других типов IPC: сокеты домена unix, TCP / IP и каналы далеко ...