Общая память POSIX против Dynami c Ссылка Библиотеки / объекты в C - PullRequest
0 голосов
/ 21 февраля 2020

Я учу себя C и начинаю понимать, что мой инструктор не самый лучший; -)

Использование G CC на Linux.

Я разрабатываю базу данных временных рядов для сбора данных IOT, которая предназначена для работы на компьютерах с ограниченными ресурсами (Pi zeros, et c).
Я хочу иметь возможность использовать несколько сборщиков данных, питающих одну базу данных, и Я хочу иметь возможность добавлять / удалять сборщики данных на лету.

Первоначально я написал его для использования dlopen () для загрузки библиотек на основе файла конфигурации. Чтобы изменить библиотеки, я просто обновляю файл конфигурации, а затем отправляю основной программе SIGUSER2, чтобы она перезагрузилась. Пока все работает нормально.

Я решил, что хочу иметь возможность обмениваться данными в реальном времени с другими приложениями, поэтому после сравнения различных типов IP C я решил использовать POSIX. стиль общей памяти. Если я правильно понимаю, даже если я использую относительно небольшую структуру (скажем, 60 байт) в разделяемой памяти, она выделит 1 страницу (4 КБ) памяти?

Предполагая, что это правильно, мне кажется, что Возможно, мне было бы лучше использовать разделяемую память для связи со сборщиками данных и запускать их как отдельные программы. Я мог бы предварительно назначить отдельные переменные массивы внутри структуры для каждого сборщика данных, а затем сделать так, чтобы основное приложение сигнализировало их по очереди, чтобы они могли выполнять запись в SHM. Помимо упрощения основного кода приложения, это также несколько изолировало бы его от сборщиков данных. Если один из них потерпит крах, это не остановит основное приложение. Сборщики данных могут запускаться и останавливаться в любое время без перезагрузки основного приложения. Кроме того, поскольку это разделяемая память, другие приложения могут считывать данные с коллекторов в режиме реального времени.

Вопросы: я думаю, что для этого потребуется меньше ресурсов, поскольку мне больше не нужно будет использовать dlopen (), не так ли? кажется правильным?

Кто-нибудь видит какие-либо существенные проблемы с этой идеей?

Самое главное, я прав, полагая, что любое приложение может читать (предполагая, что чтения являются атомами c) из общего ресурса память в любое время без необходимости координировать это?

1 Ответ

0 голосов
/ 21 февраля 2020

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

Использование Dynami * Модули 1014 * позволяют загружать / выгружать эти модули во время выполнения, так что это хорошая идея для фрагментов кода, которые будут загружаться или удаляться во время выполнения (например, если вы решите начать использовать новую версию этого протокола IoT, и вы не не хочу останавливать других от этого.

как только разрешены возможности, которые вы имеете с нами в динамически загружаемых модулях, давайте go обратимся к другой проблеме:

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

Хороший пример библиотека - это библиотека потоков POSIX (libpthread), которая реализует все механизмы блокировки как мьютекс, условные переменные, семафоры и т. п.

Чтобы использовать обе вещи вместе, вы можете определить API регистрации, чтобы разрешить основной поток для загрузки (dlopen) общего исполняемого файла, скомпилированного отдельно, и начала сбора данных в отдельном потоке, в то время как другие потоки работают с различными частями вашей базы данных. Вы можете определить даже различные типы модулей, один для CoAP, другой для M2M, другой для op c -ua и другой для асинхронного сброса всех данных вашей памяти в базу данных sql, как пример того, что вы можете делать. Если вы правильно его структурируете, вы можете получить очень хороший подход, который отлично работает на небольших устройствах, таких как Raspberry или меньше.

...