Порівняння Unix / Linux IPC


78

Unix / Linux пропонує багато IPC: канали, сокети, спільна пам’ять, dbus, черги повідомлень ...

Які програми є найбільш підходящими для кожного, і як вони працюють?


1
dbus реалізований поверх інших типів IPC: сокет доменів Unix, TCP / IP та канали далеко ...
Суддя Мейгарден,

Відповіді:


100

Unix IPC

Ось велика сімка:

  1. Труба

    Корисно лише серед процесів, пов’язаних з батьком / дитиною. Телефонуйте pipe(2)і fork(2). Однонаправлений.

  2. FIFO , або названа труба

    Два не пов'язаних між собою процеси можуть використовувати FIFO на відміну від звичайної труби. Телефонуйте mkfifo(3). Однонаправлений.

  3. Сокет та Unix доменний сокет

    Двонаправлений. Призначений для мережевого зв'язку, але може використовуватися і локально. Може використовуватися для різних протоколів. Для TCP немає межі повідомлень. Телефонуйте socket(2).

  4. Черга повідомлень

    ОС підтримує дискретні повідомлення. Див SYS / msg.h .

  5. Сигнал

    Signal надсилає ціле число до іншого процесу. Не добре поєднується з багатопотоками. Телефонуйте kill(2).

  6. Семафор

    Механізм синхронізації для багатьох процесів або потоків, подібний до черги людей, які очікують на ванну. Див SYS / sem.h .

  7. Спільна пам’ять

    Зробіть свій власний контроль паралельності. Телефонуйте shmget(2).

Проблема з межею повідомлень

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

Розглянемо пару ехо-клієнта та сервера. Клієнт надсилає рядок, сервер отримує його і відправляє назад. Припустимо, клієнт надсилає "Привіт", "Привіт" і "Як щодо відповіді?".

З протоколами байтових потоків сервер може отримувати як "Пекло", "oHelloHow" і "про відповідь?"; або більш реально "HelloHelloА як щодо відповіді?". Сервер не знає, де знаходиться межа повідомлення.

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

З дискретними протоколами, такими як UDP або черги повідомлень, вам не доведеться турбуватися про цю проблему, але з програмними потоками байтів легше мати справу, оскільки вони поводяться як файли та stdin / out.


Я думаю, ви могли б туди включити семафори, але я бачу це більше як інструмент одночасності, ніж як інструмент міжпроцесорного зв'язку.
Євген Йокота

2
До речі, ви можете надсилати дескриптори файлів через сокет домену Unix [ linux.die.net/man/7/unix]
Гастуркун,

2
Один незначний nit: pipe (2) також може бути використаний у процесах побратимства - наприклад, оболонка є батьківською для всіх процесів у трубопроводі.
Хадсон,

5
Зверніть увагу, що ви можете мати орієнтовані на повідомлення сокети доменів Unix. На відміну від Інтернет, вони надійні.
Том Андерсон,

2
Чи існує орієнтир або якісне порівняння результатів цих підходів?
kakyo

17

Спільна пам’ять може бути найефективнішою, оскільки ви будуєте свою власну схему спілкування поверх неї, але вона вимагає великої уваги та синхронізації. Доступні рішення для розподілу спільної пам'яті на інших машинах.

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

Черги повідомлень та сигнали можуть бути чудовими для жорстких програм реального часу, але вони не настільки гнучкі.

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


З мого досвіду, названі труби можуть бути настільки ж швидкими та безпечними, як майже будь-який інший спосіб.
Ерік Аронесті

10

Ось веб-сторінка з простим тестом: https://sites.google.com/site/rikkus/sysv-ipc-vs-unix-pipes-vs-unix-sockets

Наскільки я можу зрозуміти, у кожного є свої переваги:

  • Трубопровідний ввід / вивід є найшвидшим, але для роботи йому потрібні стосунки батьків / дитини.
  • Sysv IPC має визначену межу повідомлень і може локально підключати різні процеси.
  • Сокети UNIX можуть локально підключати різні процеси та мають більшу пропускну здатність, але не мають властивих меж повідомлень.
  • Сокети TCP / IP можуть підключати будь-які процеси, навіть по мережі, але мають вищі накладні витрати і не мають властивих меж повідомлень.


як порівняти dbus з іншими?
BЈовић

DBUS використовує один або кілька з цих механізмів. Існує багаторічна робота над їх власним механізмом IPC, який називається DBUS1 (або KDBUS ...), але він все ще не об’єднаний в основне ядро.
Філіп Вілан

8

Варто зазначити, що багато бібліотек реалізують один тип речей один на одному.

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


Я ніколи раніше не чув про mmaping / dev / zero. Геніальне! Ви згадуєте, що ним можна ділитися лише з дітьми, але чи можете ви надіслати дескриптор файлу, який ви використовуєте, до не пов’язаного між собою процесу, використовуючи cmsg / SCM_RIGHTS через сокет Unix-домену, і закінчити там спільним відображенням? Або це відображення, яке ви успадковуєте, а не дескриптор файлу? Навіть якщо це працює, вам все одно потрібен сокет десь у файловій системі, щоб зробити це, тому навіть якщо відображення анонімне, сокет, який використовувався для його налаштування, ні. Га МПК важко. Ходімо за покупками!
Том Андерсон,

mmaping / dev / zero фактично використовується деякими видами виділення пам'яті. Але перевага полягає в тому, що якщо ви використовуєте MAP_SHARED, він отримує спільний доступ із вашими дочірніми процесами fork () (нормальна пам'ять копіюється логічно). Чи можете ви поділитися цим з не пов'язаним процесом? Я не думаю. Я підозрюю, що виклик mmap () повинен бути спільним, а не дескриптор файлу.
MarkR
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.