Обмен данными локально (как с сокетами) между несколькими программами в C ++ - PullRequest
5 голосов
/ 20 декабря 2011

Моя цель - отправлять / делиться данными между несколькими программами .Вот варианты, о которых я подумал:

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

Я выбрал последний.

Итак, каков эффективный способ отправки данных из одной программы в другую?Например, он может использовать буфер , записывать в него байты и ждать, пока получатель не пометит первый байт как «прочитанный» (в основном, что-нибудь еще, кроме записанного байта) ,затем напишите снова, но , куда я бы поместил буфер и как сделать его доступным для обеих программ?Или, может быть, что-то еще тоже может работать?

Я использую Linux.

Ответы [ 6 ]

4 голосов
/ 20 декабря 2011

А как насчет fifos и труб?Если вы работаете в среде Linux, это позволяет двум программам обмениваться данными.

4 голосов
/ 20 декабря 2011

Самым быстрым IPC для процессов, запущенных на одном хосте, является разделяемая память.

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

См. Это учебное пособие .

3 голосов
/ 20 декабря 2011

Вы можете взглянуть на Boost.Interprocess

Boost.Interprocess упрощает использование общих механизмов межпроцессного взаимодействия и синхронизации и предлагает широкий спектр из них:

  • Общая память.

  • Отображенные в память файлы.

  • Семафоры, мьютексы, условные переменные и обновляемые типы мьютексов для размещения их в общих память и отображенные в память файлы.

  • Именованные версии этих объектов синхронизации, аналогично UNIX / Windows sem_open / CreateSemaphore API.

  • Блокировка файла.

  • Относительные указатели.

  • Очереди сообщений.

2 голосов
/ 20 декабря 2011

Чтобы ответить на ваши вопросы:

Использование файла, вероятно, не лучший способ, и файлы обычно не используются для передачи информации о внутреннем процессе. Помните, что ОС должна открывать, читать, писать, закрывать их. Однако они используются для блокировки (http://en.wikipedia.org/wiki/File_locking).

Наивысшая производительность, которую вы получаете, используя pipestream (http://linux.die.net/man/3/popen),, но в Linux трудно понять, что нужно. Вы должны перенаправить stdin, stdout и stderr. Это должно быть сделано для каждого внутреннего процесса. это будет хорошо работать для двух приложений, но выходить за рамки этого и становится очень волосатым.

Мое любимое решение, использовать пары сокетов (http://pubs.opengroup.org/onlinepubs/009604499/functions/socketpair.html). Они очень надежны и просты в настройке. Но если вы используете несколько приложений, вам нужно подготовить какой-то пул для доступа к приложениям.

2 голосов
/ 20 декабря 2011

В Linux при использовании файлов они очень часто находятся в кеше, поэтому вы не будете часто читать диск, и вы можете использовать файловую систему «RAM», такую ​​как tmpfs (на самом деле tmpfs использовать виртуальную память, поэтому RAM + swap, и практически все файлы хранятся в оперативной памяти большую часть времени).

Основной проблемой остается синхронизация .

Использование сокетов (возможно, если все процессы находятся на одном компьютере, AF_UNIX сокетов, которые работают быстрее, чем TCP / IP), имеет преимущество, заключающееся в том, что наш код легко переносится в среды, где вы предпочитаете запустить несколько процессов на нескольких машинах.

И вы также можете использовать существующую платформу для параллельного выполнения, например, например. MPI , Корба и т. Д. И т. Д.

Вы должны иметь общее представление о пропускной способности и задержке, ожидаемых от вашего приложения. (это не то же самое, если вам нужно разделить десятки мегабайт каждую миллисекунду или сотни килобайт каждые десятые секунды).

Я бы предложил больше узнать о сериализации методах, форматах и ​​библиотеках, таких как XDR, ASN1, JSON, YAML, s11n , jsoncpp и т. Д.

И отправка или обмен данными не совпадают. Когда вы отправляете (и получаете) данные, вы думаете с точки зрения передачи сообщений. Когда вы обмениваетесь данными, вы думаете с точки зрения общей памяти. Стиль программирования очень отличается.

0 голосов
/ 20 декабря 2011

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

Но если вы используете сокеты (многоадресные сокеты), то реализация будет немного сложнее, но масштабируемость и ремонтопригодность очень просты.Вам не нужно беспокоиться о том, сколько приложений будет ожидать данных, вы можете просто выполнить многоадресную рассылку, и они будут прослушивать данные и обрабатывать их.Нет необходимости ждать, пока семафор (метод синхронизации совместно используемой памяти) прочитает данные.

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

Производительность, масштабируемость и удобство обслуживания будут иметь дополнительные преимущества при использовании сокетов.

С уважением,
SSuman185

...