Совместное использование одной и той же переменной между несколькими независимыми программами в Linux

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

Ответ 1

Переменные, которые вы объявляете в своих заголовках, будут генерировать копию, где бы вы ни включали их (если вы не объявите их extern). Конечно, при работе с отдельными процессами каждый процесс будет иметь собственное пространство памяти. Вам необходимо использовать более сложные методы, чтобы обойти это, то есть Inter Process Communication (IPC). Например:

  • (named) Pipes
  • Розетки
  • Общая память

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

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

Когда вы закончите с вашей общей памятью, вам нужно отсоединить (shmdt). Тем самым вы сообщаете ядру, что ваш процесс больше не нуждается в доступе к нему. Процесс, который создал объект shared memory/semaphore, также должен уничтожить их в конце вашей программы (ов). В противном случае он будет находиться в памяти, вероятно, до тех пор, пока вы не перезагрузите компьютер (см. shmctl, semctl, особенно IPC_RMID).

Обратите внимание, что для объектов общей памяти "сегмент будет фактически уничтожен только после того, как последний процесс отделит его". Поэтому вы хотите убедиться, что это действительно происходит для всех ваших процессов (shmdt).


В ответ на комментарии, вот подход POSIX:

Общий доступ к системе V (shmget (2), shmop (2) и т.д.) является более старым API общей памяти. Общая память POSIX обеспечивает более простой и улучшенный интерфейс; с другой стороны, разделяемая память POSIX несколько менее доступна (особенно в старых системах), чем в общей памяти System V.

  • shm_open - для получения общей памяти (через дескриптор файла)
  • ftruncate - установить размер разделяемой памяти
  • mmap - чтобы получить указатель на память
  • sem_open - для получения семафора
  • sem_wait, sem_post - для синхронизации чтения/записи
  • shm_unlink, sem_close - очистить после всех

См. также этот обзор и здесь для примеры.

Наконец, обратите внимание, что

Объекты разделяемой памяти POSIX имеют стойкость ядра: объект общей памяти будет существовать до тех пор, пока система не будет отключена, или пока все процессы не удалили объект и не были удалены с помощью shm_unlink (3)


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

Ответ 2

Посмотрите на использование общей памяти POSIX с помощью shm_open и shm_unlink... Я лично считаю, что они проще в использовании и более прямолинейны, чем предыдущие вызовы IPC System-V, такие как shmget и т.д., так как возвращаемый дескриптор работает точно так же, как файловый дескриптор, который вы может использоваться с такими вызовами, как read, write и т.д. В противном случае, если вы хотите получить доступ к объекту разделяемой памяти, представленному файловым дескриптором, с помощью обычных указателей, вы можете использовать mmap в дескрипторе файла, возвращаемом shm_open.