Unix / Linux пропонує багато IPC: канали, сокети, спільна пам’ять, dbus, черги повідомлень ...
Які програми є найбільш підходящими для кожного, і як вони працюють?
Unix / Linux пропонує багато IPC: канали, сокети, спільна пам’ять, dbus, черги повідомлень ...
Які програми є найбільш підходящими для кожного, і як вони працюють?
Відповіді:
Ось велика сімка:
Корисно лише серед процесів, пов’язаних з батьком / дитиною. Телефонуйте pipe(2)
і fork(2)
. Однонаправлений.
FIFO , або названа труба
Два не пов'язаних між собою процеси можуть використовувати FIFO на відміну від звичайної труби. Телефонуйте mkfifo(3)
. Однонаправлений.
Двонаправлений. Призначений для мережевого зв'язку, але може використовуватися і локально. Може використовуватися для різних протоколів. Для TCP немає межі повідомлень. Телефонуйте socket(2)
.
ОС підтримує дискретні повідомлення. Див SYS / msg.h .
Signal надсилає ціле число до іншого процесу. Не добре поєднується з багатопотоками. Телефонуйте kill(2)
.
Механізм синхронізації для багатьох процесів або потоків, подібний до черги людей, які очікують на ванну. Див SYS / sem.h .
Зробіть свій власний контроль паралельності. Телефонуйте shmget(2)
.
Одним із визначальних факторів при виборі одного методу над іншим є проблема межі повідомлення. Ви можете очікувати, що "повідомлення" будуть дискретними один від одного, але це не стосується байтових потоків, таких як TCP або Pipe.
Розглянемо пару ехо-клієнта та сервера. Клієнт надсилає рядок, сервер отримує його і відправляє назад. Припустимо, клієнт надсилає "Привіт", "Привіт" і "Як щодо відповіді?".
З протоколами байтових потоків сервер може отримувати як "Пекло", "oHelloHow" і "про відповідь?"; або більш реально "HelloHelloА як щодо відповіді?". Сервер не знає, де знаходиться межа повідомлення.
Старовинна хитрість полягає в тому, щоб обмежити довжину повідомлення CHAR_MAX
або або UINT_MAX
погодитись надіслати довжину повідомлення першим у char
або uint
. Отже, якщо ви знаходитесь на приймаючій стороні, вам слід спочатку прочитати довжину повідомлення. Це також означає, що читати повідомлення одночасно повинен лише один потік.
З дискретними протоколами, такими як UDP або черги повідомлень, вам не доведеться турбуватися про цю проблему, але з програмними потоками байтів легше мати справу, оскільки вони поводяться як файли та stdin / out.
Спільна пам’ять може бути найефективнішою, оскільки ви будуєте свою власну схему спілкування поверх неї, але вона вимагає великої уваги та синхронізації. Доступні рішення для розподілу спільної пам'яті на інших машинах.
На сьогоднішній день розетки є найбільш портативними, але вимагають більше накладних витрат, ніж труби. Можливість прозоро використовувати сокети локально або через мережу - чудовий бонус.
Черги повідомлень та сигнали можуть бути чудовими для жорстких програм реального часу, але вони не настільки гнучкі.
Ці методи, природно, були створені для зв'язку між процесами, і використання декількох потоків у процесі може ускладнити ситуацію - особливо за допомогою сигналів.
Ось веб-сторінка з простим тестом: https://sites.google.com/site/rikkus/sysv-ipc-vs-unix-pipes-vs-unix-sockets
Наскільки я можу зрозуміти, у кожного є свої переваги:
Варто зазначити, що багато бібліотек реалізують один тип речей один на одному.
Спільна пам'ять не повинна використовувати жахливі функції спільної пам'яті sysv - набагато елегантніше використовувати mmap () (mmap файл у файлі tmpfs / dev / shm, якщо ви хочете, щоб він був названий; mmap / dev / zero, якщо хочете forked не виконував процеси, щоб успадковувати його анонімно). Сказавши це, він все ще залишає ваші процеси певною необхідністю синхронізації, щоб уникнути проблем - як правило, за допомогою деяких інших механізмів IPC для синхронізації доступу до області спільної пам'яті.