Мультиобработка с использованием синглетонов C ++ в Linux x86_64 - PullRequest
2 голосов
/ 16 марта 2012

Для следующего вопроса я ищу ответ, основанный на «чистых» основах C / C ++, поэтому я был бы признателен за не-Boost ответ. Спасибо.

У меня есть приложение (например, сервер телекоммуникационной инфраструктуры), которое при запуске порождает несколько процессов в среде Linux (один для ведения журнала, один для управления таймером, один для обмена сообщениями по протоколу, один для обработки сообщений и т. Д.). ). Он находится в среде x86_64 в Gentoo. Дело в том, что мне нужен синглтон, чтобы быть доступным для всех процессов.

Это отличается от многопоточности, использующей, скажем, потоки POSIX, в Linux, потому что одно и то же адресное пространство используется всеми потоками POSIX, но это не тот случай, когда используется несколько процессов, генерируемых вызовом функции fork (). , Когда используется одно и то же адресное пространство, синглтон - это один и тот же адрес во всех потоках, и проблема решается тривиально (с использованием хорошо известных средств защиты, которые являются устаревшими для всех на SO). Мне нравятся средства защиты, предлагаемые мне несколькими процессами, генерируемыми с помощью fork ().

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

Я представляю себе следующее (SomeSingleton.h):

#include <unistd.h>
#... <usual includes>
#include "SomeGiantObject.h"

int size = 8192; // Enough to contain the SomeSingleton object
int shm_fd = shm_open ("/some_singleton_shm", O_CREAT | O_EXCL | O_RDWR, 0666);
ftruncate (shm_fd, size);
sharedMemoryLocationForSomeSingleton = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);

class SomeSingleton
{
   public:
     SomeSingleton* getInstance ()
     {
        return reinterpret_cast<SomeSingleton*>sharedMemoryLocationForSomeSingleton;
     }
   private:
     SomeSingleton();
     /*
        Whole bunch of attributes that is shared across processes.
        These attributes also should be in shared memory.
        e.g., in the following
        SomeGiantObject* obj;
        obj should also be in shared memory.
     */
};

Метод getInstance () возвращает расположение общей памяти для объекта SomeSingleton.

У меня следующие вопросы:

  1. Является ли это законным способом решения проблемы? Как люди на SO решали эту проблему раньше?
  2. Чтобы приведенный выше код работал, я представляю глобальное объявление (статическое по определению), которое указывает на разделяемую память, как показано перед объявлением класса.
  3. Наконец, но не в последнюю очередь, я знаю, что в Linux накладные расходы на создание потоков и процессов "относительно схожи", но мне было интересно, почему в SO много дискуссий о SO (gob) нагрузка многопоточности, хотя!). Здесь даже нет тега! Многочисленная обработка (с использованием fork ()) перестала пользоваться популярностью среди разработчиков C ++? Любое понимание этого также приветствуется. Кроме того, могу ли я попросить кого-нибудь с репутацией> 1500 создать тег "мультиобработка?" Спасибо.

1 Ответ

1 голос
/ 16 марта 2012

Если вы создадите область совместно используемой памяти перед разветвлением, то она будет отображаться по одному и тому же адресу во всех пирах.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...