Какие способы межпроцессного взаимодействия существуют на одной машине
Что проверяют
Знаете ли вы механизмы ОС дальше «можно через сокет» и умеете ли выбрать под задачу: объём данных, задержку, родство процессов. Следом почти всегда спрашивают, как синхронизировать доступ к разделяемой памяти.
Как отвечать
Сгруппируйте способы по характеру обмена:
- анонимный канал (
pipe): байтовый поток в одну сторону между родственными процессами, обычно послеfork. Буфер ядра ограничен (в Linux по умолчанию 64 КиБ), при заполнении запись блокируется; - именованный канал (FIFO,
mkfifo): тот же поток, но с именем в файловой системе, поэтому подключаются и неродственные процессы. В Windows естьCreateNamedPipe, и там канал может быть двунаправленным; - Unix domain socket (
AF_UNIX): самый универсальный вариант. Двусторонний, есть режимы потока и датаграмм, умеет передавать файловые дескрипторы; - разделяемая память (
shm_openиmmap): самый быстрый способ, данные не копируются через ядро. Взамен синхронизацию пишете вы:sem_open, мьютекс с атрибутомPTHREAD_PROCESS_SHAREDили lock-free кольцевой буфер наstd::atomic; - очереди сообщений (
mq_open): сохраняют границы сообщений и приоритеты, но ограничены размером и числом сообщений; - сигналы и
eventfd: уведомление о событии почти без данных.
В C++ кроссплатформенно это закрывают Boost.Interprocess (разделяемая память, мьютексы, очереди) и Boost.Asio для локальных сокетов. Вывод для ответа: для команд и RPC берите Unix socket, для больших потоков с жёсткой задержкой разделяемую память.
Где спотыкаются
Кладут в разделяемую память std::string или std::vector с обычным аллокатором. Указатели внутри валидны только в адресном пространстве создателя, во втором процессе это мусор. Нужны плоские структуры, смещения вместо указателей или аллокаторы Boost.Interprocess.
Считают сигналы способом передать данные. Обычные сигналы одного типа не копятся в очередь и сливаются в один, а в обработчике разрешены только async-signal-safe функции: printf и malloc там нельзя.
Забывают про очистку. Объекты shm_open и очереди System V живут после смерти процесса, и после падения их удаляют через shm_unlink или ipcrm.