IPC: каналы, сокеты, сигналы и общая память
IPC — взаимодействие процессов: передача данных и согласование действий. Не каждый механизм работает между компьютерами. Например, локальный pipe или shared memory относятся к одной системе, а сетевой сокет может связывать разные машины. Сам факт обмена не решает все вопросы доставки, границ сообщений и прав.
Содержание статьи
Чем различаются механизмы
| Механизм | Подходит для | Что нужно учесть |
|---|---|---|
| Pipe | Поток данных между связанными процессами | Закрытие концов, EOF, буфер и блокировки |
| Сокет | Локальный сервис или обмен по сети | Тип сокета, протокол, framing, timeout и аутентификация |
| Сигнал | Уведомление о событии или управлении | Ограничения обработчика; это не канал произвольных больших объектов |
| Очередь сообщений | Передача отдельных сообщений | Границы, порядок, лимиты и подтверждения зависят от реализации |
| Общая память | Совместный доступ к массивам данных | Синхронизация и жизненный цикл; гонки не исчезают автоматически |
Пример Python: одно сообщение между процессами
import multiprocessing as mp
def produce(connection):
try:
connection.send_bytes(b"ready")
finally:
connection.close()
if __name__ == "__main__":
context = mp.get_context("spawn")
receiver, sender = context.Pipe(duplex=False)
worker = context.Process(target=produce, args=(sender,))
worker.start()
sender.close()
try:
if not receiver.poll(5):
raise TimeoutError("No IPC message")
print(receiver.recv_bytes(maxlength=32))
finally:
receiver.close()
worker.join(timeout=5)
if worker.is_alive():
worker.terminate()
worker.join()Сохраните пример в отдельный .py-файл и запустите как программу; при spawn дочерний процесс должен импортировать функцию produce. Ожидаемый вывод — b'ready'. Это Connection-обёртка multiprocessing с сообщениями, а не обещание, что обычный POSIX pipe хранит границы произвольных записей.
Условия, которые часто забывают
- Закрывайте неиспользуемые концы канала: оставшаяся открытая запись способна помешать обнаружить EOF.
- Не передавайте чужие недоверенные данные в recv(), который восстанавливает Python-объекты через pickle. В примере выбраны bytes и явный лимит.
- Продумайте выход при зависании и падении другой стороны. Timeout и cleanup должны иметь понятный смысл.
- Измеряйте копирование, сериализацию и синхронизацию на своём объёме данных. Shared memory не является универсальным ускорителем для любого обмена.