在Linux中的多个独立程序之间共享相同的变量

时间:2021-08-16 16:47:17

I want to share a variable between more than one independent C executables in Linux. That is, a program will write on an array and set a flag so that no other program can use it, and after this operation it'll unset the flag and then another program will read the array. I tried using the same custom header file (containing the variable) in every program, but it seems different instances of the variables are created when the programs are invoked.

我想在Linux*享一个以上的独立C可执行文件之间的变量。也就是说,程序将在数组上写入并设置一个标志,以便其他程序无法使用它,并且在此操作之后它将取消设置该标志,然后另一个程序将读取该数组。我尝试在每个程序中使用相同的自定义头文件(包含变量),但似乎在调用程序时会创建不同的变量实例。

2 个解决方案

#1


14  

Variables you declare in your headers will generate a copy where ever you include them (unless you declare them extern). Of course, when dealing with separate processes every process will have its own memory space. You need to use more sophisticated techniques to circumvent this, i.e. Inter Process Communication (IPC). For example:

您在标题中声明的变量将生成一个包含它们的副本(除非您将它们声明为extern)。当然,在处理单独的进程时,每个进程都会有自己的内存空间。您需要使用更复杂的技术来规避这一点,即进程间通信(IPC)。例如:

  • (named) Pipes
  • (命名)管道
  • Sockets
  • 套接字
  • Shared Memory
  • 共享内存

Your question reads like shared memory is what you want, since hereby multiple processes can access the same memory regions to share some variables. Maybe take a look at this question and its answers for an example.

您的问题读起来就像您想要的共享内存,因为多个进程可以访问相同的内存区域来共享一些变量。也许看看这个问题及其答案的例子。

Your program would be required to create some shared memory, e.g. using shmget and to attach the shared memory object using shmat. When multiple processes access same memory regions, it's always a healthy approach to add process synchronization during read/write on the variable, e.g. using a shared semaphore (semget, semop).

您的程序将需要创建一些共享内存,例如使用shmget并使用shmat附加共享内存对象。当多个进程访问相同的内存区域时,在读取/写入变量期间添加进程同步始终是一种健康的方法,例如,使用共享信号量(semget,semop)。

When you are done with your shared memory you need to detach (shmdt) from it. Thereby you tell the kernel that your process no longer needs access to it. The process that created the shared memory/semaphore object also needs to destroy them at the end of your program(s). Otherwise it will reside in memory, probably until you reboot your machine (see shmctl, semctl, especially IPC_RMID).

完成共享内存后,需要从中分离(shmdt)。因此,您告诉内核您的进程不再需要访问它。创建共享内存/信号量对象的进程也需要在程序结束时销毁它们。否则它将驻留在内存中,可能直到您重新启动计算机(请参阅shmctl,semctl,尤其是IPC_RMID)。

Note that for shared memory objects "The segment will only actually be destroyed after the last process detaches it". So you want to make sure, that this actually happens for all of your processes (shmdt).

请注意,对于共享内存对象“只有在最后一个进程分离后,才会实际销毁该段”。所以你要确保,这实际上发生在你的所有进程(shmdt)上。


In response to the comments, here is the POSIX approach:

在回应评论时,这是POSIX方法:

System V shared memory (shmget(2), shmop(2), etc.) is an older shared memory API. POSIX shared memory provides a simpler, and better designed interface; on the other hand POSIX shared memory is somewhat less widely available (especially on older systems) than System V shared memory.

System V共享内存(shmget(2),shmop(2)等)是较旧的共享内存API。 POSIX共享内存提供了一个更简单,设计更好的界面;另一方面,与System V共享内存相比,POSIX共享内存在某种程度上不太可用(特别是在旧系统上)。

  • shm_open - to get shared memory (via file descriptor)
  • shm_open - 获取共享内存(通过文件描述符)
  • ftruncate - to set the size of the shared memory
  • ftruncate - 设置共享内存的大小
  • mmap - to get a pointer to the memory
  • mmap - 获取指向内存的指针
  • sem_open - to get a semaphore
  • sem_open - 获取信号量
  • sem_wait, sem_post - for your read/write synchronisation
  • sem_wait,sem_post - 用于读/写同步
  • shm_unlink, sem_close - to clean up after all
  • shm_unlink,sem_close - 毕竟要清理

See also this overview and here for examples.

另请参见此概述和此处的示例。

Finally, note that

最后,请注意

POSIX shared memory objects have kernel persistence: a shared memory object will exist until the system is shut down, or until all processes have unmapped the object and it has been deleted with shm_unlink(3)

POSIX共享内存对象具有内核持久性:共享内存对象将一直存在,直到系统关闭,或者直到所有进程都已取消映射该对象并且已使用shm_unlink删除它(3)


In order to take into account the persistence of the shared memory objects, don't forget to add signal handlers to your application that will perform the clean up operations in case of an exceptional termination (SIGINT, SIGTERM etc.).

为了考虑共享内存对象的持久性,不要忘记向应用程序添加信号处理程序,以便在异常终止(SIGINT,SIGTERM等)的情况下执行清理操作。

#2


6  

Look into using POSIX shared memory via shm_open and shm_unlink... I personally feel they are easier to use and more straight-forward than the older System-V IPC calls such as shmget, etc. since the handle returned works exactly like a file-descriptor that you can use with calls like read, write, etc. Otherwise, if you want access the shared memory object represented by the file-descriptor via normal pointers, you can use mmap on the file-descriptor returned by shm_open.

通过shm_open和shm_unlink考虑使用POSIX共享内存...我个人认为它们比旧的System-V IPC调用(如shmget等)更容易使用和更直接,因为返回的句柄与文件完全相同 - 您可以使用读取,写入等调用的描述符。否则,如果要通过普通指针访问由文件描述符表示的共享内存对象,则可以在shm_open返回的文件描述符上使用mmap。

#1


14  

Variables you declare in your headers will generate a copy where ever you include them (unless you declare them extern). Of course, when dealing with separate processes every process will have its own memory space. You need to use more sophisticated techniques to circumvent this, i.e. Inter Process Communication (IPC). For example:

您在标题中声明的变量将生成一个包含它们的副本(除非您将它们声明为extern)。当然,在处理单独的进程时,每个进程都会有自己的内存空间。您需要使用更复杂的技术来规避这一点,即进程间通信(IPC)。例如:

  • (named) Pipes
  • (命名)管道
  • Sockets
  • 套接字
  • Shared Memory
  • 共享内存

Your question reads like shared memory is what you want, since hereby multiple processes can access the same memory regions to share some variables. Maybe take a look at this question and its answers for an example.

您的问题读起来就像您想要的共享内存,因为多个进程可以访问相同的内存区域来共享一些变量。也许看看这个问题及其答案的例子。

Your program would be required to create some shared memory, e.g. using shmget and to attach the shared memory object using shmat. When multiple processes access same memory regions, it's always a healthy approach to add process synchronization during read/write on the variable, e.g. using a shared semaphore (semget, semop).

您的程序将需要创建一些共享内存,例如使用shmget并使用shmat附加共享内存对象。当多个进程访问相同的内存区域时,在读取/写入变量期间添加进程同步始终是一种健康的方法,例如,使用共享信号量(semget,semop)。

When you are done with your shared memory you need to detach (shmdt) from it. Thereby you tell the kernel that your process no longer needs access to it. The process that created the shared memory/semaphore object also needs to destroy them at the end of your program(s). Otherwise it will reside in memory, probably until you reboot your machine (see shmctl, semctl, especially IPC_RMID).

完成共享内存后,需要从中分离(shmdt)。因此,您告诉内核您的进程不再需要访问它。创建共享内存/信号量对象的进程也需要在程序结束时销毁它们。否则它将驻留在内存中,可能直到您重新启动计算机(请参阅shmctl,semctl,尤其是IPC_RMID)。

Note that for shared memory objects "The segment will only actually be destroyed after the last process detaches it". So you want to make sure, that this actually happens for all of your processes (shmdt).

请注意,对于共享内存对象“只有在最后一个进程分离后,才会实际销毁该段”。所以你要确保,这实际上发生在你的所有进程(shmdt)上。


In response to the comments, here is the POSIX approach:

在回应评论时,这是POSIX方法:

System V shared memory (shmget(2), shmop(2), etc.) is an older shared memory API. POSIX shared memory provides a simpler, and better designed interface; on the other hand POSIX shared memory is somewhat less widely available (especially on older systems) than System V shared memory.

System V共享内存(shmget(2),shmop(2)等)是较旧的共享内存API。 POSIX共享内存提供了一个更简单,设计更好的界面;另一方面,与System V共享内存相比,POSIX共享内存在某种程度上不太可用(特别是在旧系统上)。

  • shm_open - to get shared memory (via file descriptor)
  • shm_open - 获取共享内存(通过文件描述符)
  • ftruncate - to set the size of the shared memory
  • ftruncate - 设置共享内存的大小
  • mmap - to get a pointer to the memory
  • mmap - 获取指向内存的指针
  • sem_open - to get a semaphore
  • sem_open - 获取信号量
  • sem_wait, sem_post - for your read/write synchronisation
  • sem_wait,sem_post - 用于读/写同步
  • shm_unlink, sem_close - to clean up after all
  • shm_unlink,sem_close - 毕竟要清理

See also this overview and here for examples.

另请参见此概述和此处的示例。

Finally, note that

最后,请注意

POSIX shared memory objects have kernel persistence: a shared memory object will exist until the system is shut down, or until all processes have unmapped the object and it has been deleted with shm_unlink(3)

POSIX共享内存对象具有内核持久性:共享内存对象将一直存在,直到系统关闭,或者直到所有进程都已取消映射该对象并且已使用shm_unlink删除它(3)


In order to take into account the persistence of the shared memory objects, don't forget to add signal handlers to your application that will perform the clean up operations in case of an exceptional termination (SIGINT, SIGTERM etc.).

为了考虑共享内存对象的持久性,不要忘记向应用程序添加信号处理程序,以便在异常终止(SIGINT,SIGTERM等)的情况下执行清理操作。

#2


6  

Look into using POSIX shared memory via shm_open and shm_unlink... I personally feel they are easier to use and more straight-forward than the older System-V IPC calls such as shmget, etc. since the handle returned works exactly like a file-descriptor that you can use with calls like read, write, etc. Otherwise, if you want access the shared memory object represented by the file-descriptor via normal pointers, you can use mmap on the file-descriptor returned by shm_open.

通过shm_open和shm_unlink考虑使用POSIX共享内存...我个人认为它们比旧的System-V IPC调用(如shmget等)更容易使用和更直接,因为返回的句柄与文件完全相同 - 您可以使用读取,写入等调用的描述符。否则,如果要通过普通指针访问由文件描述符表示的共享内存对象,则可以在shm_open返回的文件描述符上使用mmap。