Самый быстрый способ передачи сообщений между процессами в Linux?

Какая самая быстрая технология для отправки сообщений между процессами приложения C ++ в Linux? Я смутно осознаю, что на столе лежат следующие методы:

  • TCP
  • UDP
  • Розетки
  • трубы
  • Именованные трубы
  • Отображенные в память файлы

Есть ли еще способы и какой самый быстрый?

29

Решение

Я бы посоветовал посмотреть на это также: Как использовать разделяемую память с Linux в C.

По сути, я бы отбросил сетевые протоколы, такие как TCP и UDP, когда выполняю IPC на одной машине. Они имеют накладные расходы на упаковку и связаны с еще большим количеством ресурсов (например, портов, интерфейса обратной связи).

11

Другие решения

Хотя все приведенные выше ответы очень хороши, я думаю, что нам нужно обсудить, что является «самым быстрым» [и должно ли оно быть «самым быстрым» или просто «достаточно быстрым для»?]

Для БОЛЬШИХ сообщений нет сомнений в том, что разделяемая память — это очень хороший метод, и очень полезный во многих отношениях.

Тем не менее, если сообщения небольшие, есть недостатки, связанные с тем, что вам необходимо разработать собственный протокол передачи сообщений и метод информирования другого процесса о наличии сообщения.

В этом случае гораздо проще использовать каналы и именованные каналы — они ведут себя почти как файл, вы просто записываете данные на отправляющей стороне и считываете данные на принимающей стороне. Если отправитель что-то пишет, сторона получателя автоматически просыпается. Если труба заполнена, отправляющая сторона блокируется. Если от отправителя больше нет данных, принимающая сторона автоматически блокируется. Это означает, что это может быть реализовано в несколько строк кода с довольно хорошей гарантией того, что он будет работать всегда и всегда.

Общая память, с другой стороны, использует какой-то другой механизм для информирования другого потока, что «у вас есть пакет данных для обработки». Да, это очень быстро, если вам нужно скопировать БОЛЬШИЕ пакеты данных — но я бы удивился, если бы на самом деле была огромная разница с каналом. Основное преимущество заключается в том, что другой стороне не нужно копировать данные из общей памяти, но она также полагается на наличие достаточного объема памяти для хранения всех сообщений «в полете» или на то, что отправитель может удерживать вещи. ,

Я не говорю «не используйте разделяемую память», я просто говорю, что не существует такой вещи, как «одно решение, которое решает все проблемы« лучше »».

Чтобы уточнить: я хотел бы начать с реализации простого метода с использованием канала или именованного канала [в зависимости от того, что подходит для целей], и измерить производительность этого. Если на копирование данных тратится значительное время, я бы подумал об использовании других методов.

Конечно, еще одно соображение должно заключаться в том, «будем ли мы когда-либо использовать две отдельные машины [или две виртуальные машины в одной системе] для решения этой проблемы. В этом случае сетевое решение является лучшим выбором, даже если оно не самое быстрое». Я запустил локальный стек TCP на своих машинах на работе в целях тестирования и получил около 20-30 Гбит / с (2-3 ГБ / с) с устойчивым трафиком. Неформатированный memcpy в том же процессе получает около 50-100 Гбит / с. (5–10 ГБ / с) (если только размер блока не является ДЕЙСТВИТЕЛЬНО крошечным и не помещается в кэш L1). Я не измерял стандартный канал, но я ожидаю, что это где-то примерно посередине этих двух чисел. [Это числа которые подходят для ряда различных довольно современных ПК среднего размера — очевидно, на ARM, MIPS или другом встроенном контроллере стиля ожидайте меньшее число для всех этих методов]

36

NetOS Systems Research Group из Кембриджского университета, Великобритания, провела некоторые (открытые) тесты IPC.

Исходный код находится по адресу https://github.com/avsm/ipc-bench .

Страница проекта: http://www.cl.cam.ac.uk/research/srg/netos/projects/ipc-bench/ .

Результаты: http://www.cl.cam.ac.uk/research/srg/netos/projects/ipc-bench/results.html

Это исследование было опубликовано с использованием результатов выше: http://anil.recoil.org/papers/drafts/2012-usenix-ipc-draft1.pdf

6

Проверьте CMA и kdbus:
https://lwn.net/Articles/466304/

Я думаю, что самые быстрые вещи в наши дни основаны на AIO.
http://www.kegel.com/c10k.html

3

Поскольку вы пометили этот вопрос на C ++, я бы порекомендовал Boost.Interprocess:

Общая память — самый быстрый механизм межпроцессного взаимодействия.
операционная система отображает сегмент памяти в адресном пространстве нескольких
процессы, так что несколько процессов могут читать и писать в этой памяти
сегмент без вызова функций операционной системы. Однако нам нужно
какая-то синхронизация между процессами, которые читают и пишут
Общая память.

Источник

Я нашел одно предостережение: ограничения переносимости примитивов синхронизации. Ни OS X, ни Windows не имеют встроенной реализации для переменных условий процесса, например,
и поэтому он эмулирует их с помощью спиновых замков.

Теперь, если вы используете * nix, который поддерживает общие примитивы процесса POSIX, проблем не будет.

Совместное использование памяти с синхронизацией является хорошим подходом, когда речь идет о значительных данных.

2

Ну, вы могли бы просто иметь общий сегмент памяти между вашими процессами, используя общая память Linux ака SHM,

Это довольно легко использовать, посмотрите на ссылку для некоторых примеров.

1

очереди сообщений posix довольно быстро, но у них есть некоторые ограничения

0
По вопросам рекламы [email protected]