Linux IPC — несколько устройств записи, один читатель
-
07-07-2019 - |
Вопрос
Я никогда раньше не писал IPC C++ для Linux.
Моя проблема в том, что у меня будет несколько клиентов (писателей) и один сервер (читатель).Все это будет на одной машине.Писатели будут доставлять читателю фрагменты данных (строку/структуру).Затем считыватель прочитает их в FIFO и что-нибудь с ними сделает.
Насколько я могу судить, типами IPC в Linux являются каналы или сокеты/очереди сообщений.
Мне просто интересно, может ли кто-нибудь порекомендовать мне путь, по которому можно спуститься.Я склоняюсь к розеткам, но реальных оснований для этого у меня нет.Есть ли что-нибудь, что мне следует прочитать/понять, прежде чем отправиться в это путешествие?
Спасибо
Решение
Основной вопрос, который вам следует учитывать, — это то, какие данные вы передаете, поскольку это частично определит ваши варианты.Это сводится к тому, ограничены ли ваши данные или нет.Если он не ограничен, то подойдет что-то ориентированное на поток, например FIFO или сокеты;если это так, то вы могли бы лучше использовать такие вещи, как MQ или разделяемую память.Поскольку вы упоминаете как строки, так и структуры, трудно сказать, что подходит в вашем случае, хотя, если ваши строки ограничены некоторым разумным максимумом, вы можете использовать что угодно с небольшими манипуляциями.
Второе – это скорость.На этот вопрос никогда не существует полностью правильного ответа, но обычно он звучит примерно так:общая память, MQ, FiFO, доменные сокеты, сетевые сокеты.
В-третьих, простота использования.Общая память — это самый большой PITA, поскольку вам приходится самостоятельно выполнять синхронизацию.Каналы просты, пока длина ваших сообщений не превышает размера PIPE_BUF.ОС решает большую часть вашей головной боли с помощью MQ.Сокеты достаточно просты, но у вас есть шаблон настройки.
Наконец, некоторые механизмы IPC имеют варианты POSIX и SYSV.Обычно лучше использовать POSIX, если только тип SYSV не имеет какой-либо функции, которая вам действительно нужна или нужна.
РЕДАКТИРОВАТЬ:Ответ Count0 напомнил мне, что вас может заинтересовать что-то более абстрактное и более высокого уровня.Помимо ACE вы можете посмотреть Поко.И, конечно же, ни один SO-ответ не будет полным, если в нем не упоминается Способствовать росту где-то.
Другие советы
System V IPC несколько сложна в использовании, но это зрелая и надежная технология.Очереди сообщений, вероятно, будут делать то, что вы хотите, и поддерживать атомарную постановку в очередь/удаление очереди.
Сокеты просты в использовании, а также поддерживают связь по сети.Однако они не создают очереди, поэтому вам придется написать код управления очередью на своем сервере.Использование сокетов в C++ не сильно отличается от их использования в C.В сети есть множество руководств по этому вопросу и таких книг, как «Сетевое программирование для Unix (том 1)» Стивенса, в которых эта тема рассматривается довольно подробно.
Хорошее место, чтобы намочить ноги, это вот это учебник по сокетам.
Затем вам нужно будет потоки и мьютексы и здесь.
После вышесказанного все готово для начала игры ;-)
Хотя вы не просили книги, и поскольку ответы выше очень хороши, я лишь предлагаю вам приобрести копии этих двух томов:
Сетевое программирование UNIX, том 2, второе издание:Межпроцессные коммуникации, В.Ричард Стивенс
Расширенное программирование в среде UNIX, второе издание, В.Ричард Стивенс и Стивен А.Раго
В таком кодировании есть неизбежные тонкости, эти две книги помогут вам справиться с любой путаницей, с которой вы столкнетесь.
Попробуйте взглянуть на ТУЗ (Адаптивная коммуникационная среда).Библиотеки ACE доступны бесплатно, очень зрелые и кроссплатформенные.К сожалению, хорошей документации нет, я бы порекомендовал эта книга искать хорошее решение.Вы можете попробовать взглянуть на этот урок чтобы почувствовать закономерности (в конце документа).ACE использует набор шаблонов для очень успешного и эффективного решения этих проблем, особенно в сетевом контексте, поэтому это должно быть хорошим началом для поиска хороших шаблонов и методов для использования.
Особенно Ace_Task используя Message_Queue позвольте сделать то, что вам нужно.