Как разделить глобальные переменные в общей библиотеке (.so) между экземплярами одного и того же процесса, которые используют общую библиотеку в Linux?

У меня есть общая библиотека (.so), которую я предварительно загружаю перед запуском приложения, и у меня есть несколько глобальных структур данных в общей библиотеке, которую использует приложение. Приложение может создавать другие процессы, например, с помощью fork (), и эти процессы могут обновлять глобальные структуры данных в общей библиотеке. Я хотел бы иметь единообразное представление об этих глобальных структурах данных для всех процессов. Есть ли способ сделать это в Linux?

Я пробовал использовать вызовы shm_ * и mmap () для сопоставления глобальных данных общей библиотеки с общим сегментом, но это не сработало.


person Monk    schedule 22.11.2009    source источник


Ответы (3)


Проще говоря: вы не можете сделать именно то, что просили. Linux не поддерживает совместное использование глобальных переменных, созданных компоновщиком. Эта память будет в нераспространяемом пространстве, отображаемом в подкачку.

Общий рецепт, который я могу предложить, таков:

  1. определите структуру, которая размещает ваши данные. Никаких указателей! Просто зачет.
  2. первый процесс создает файл в / tmp, устанавливает доступ rw по мере необходимости. Откройте mmap с помощью MAP_SHARED.
  3. Последующие процессы также открываются, mmap с MAP_SHARED.
  4. каждый использует структуру, чтобы найти части, на которые они ссылаются, читают или пишут.
  5. Следите за параллелизмом!

Если вы действительно заботитесь только о родителе и его разветвленных дочерних элементах, вы можете использовать анонимное сопоставление и не беспокоиться о файле, и вы можете сохранить расположение сопоставления в глобальном (который можно прочитать в дочерних элементах).

person bmargulies    schedule 23.11.2009

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

Передайте флаги MAP_ANONYMOUS и MAP_SHARED в mmap - это будет означать, что дочерние процессы, которые наследуют сопоставление, будут иметь сопоставление, которое используется совместно с родителем (и другими дочерними процессами). Затем библиотека должна хранить структуры данных, которые будут совместно использоваться в этом сегменте памяти mmaped (точно так же, как если бы это была память, возвращенная из malloc). Очевидно, вам может понадобиться какая-то блокировка.

Функции конструктора для библиотек можно указать с помощью атрибута gcc __constructor__ function.

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

person caf    schedule 23.11.2009
comment
Это не делает то, о чем просил OP: двунаправленное совместное использование глобальных переменных. - person bmargulies; 23.11.2009
comment
Конечно, если эти глобальные переменные хранятся в общем отображении (это вполне может означать, что глобальные переменные действительно должны быть указателями, но это всего лишь деталь реализации). - person caf; 23.11.2009
comment
Он будет работать через fork (), но не через exec () (скажем, новый процесс использует ту же библиотеку), поэтому не будет работать в общем случае - person MarkR; 23.11.2009

Как насчет создания простого канала в известном местоположении каталога, а затем заставить другие процессы открывать канал для чтения / записи a la fread / fwrite соответственно для обмена данными ... сложная часть заключается в обеспечении передачи данных через канал таким образом, чтобы в этом случае не вызвать коррупции. Вышеупомянутое использование разделяемой памяти shm_ и mmap привязано к процессу, когда вы разветвляете код, это не проблема, поскольку код fork'd является частью исходного процесса! Надеюсь это поможет.

С уважением, Том.

person t0mm13b    schedule 23.11.2009