Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

Для сообщений LARGE нет сомнений в том, что разделяемая память является очень хорошей техникой и очень полезна во многих отношениях.

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

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

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

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

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

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

Ответ 3

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

Ответ 5

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

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

Источник

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

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

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

Ответ 6

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

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