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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10684499/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 06:24:52  来源:igfitidea点击:

Sharing same variable between more than one independent programs in Linux

clinuxipc

提问by Rifat Rousseau

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 可执行文件之间共享一个变量。也就是说,一个程序将写入一个数组并设置一个标志,以便其他程序不能使用它,在此操作之后它将取消设置该标志,然后另一个程序将读取该数组。我尝试在每个程序中使用相同的自定义头文件(包含变量),但似乎在调用程序时创建了不同的变量实例。

采纳答案by moooeeeep

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 memoryis what you want, since hereby multiple processes can access the same memory regions to share some variables. Maybe take a look at this questionand its answers for an example.

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

Your program would be required to create some shared memory, e.g. using shmgetand 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附加共享内存对象。当多个进程访问相同的内存区域时,在读/写变量期间添加进程同步始终是一种健康的方法,例如使用共享信号量(semgetsemop)。

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)。因此你告诉内核你的进程不再需要访问它。创建共享内存/信号量对象的进程也需要在程序结束时销毁它们。否则它将驻留在内存中,可能直到您重新启动机器(参见shmctlsemctl,尤其是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 共享内存的可用性稍差(尤其是在较旧的系统上)。

See also this overviewand herefor 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 等)的情况下执行清理操作。

回答by Jason

Look into using POSIX shared memory via shm_openand 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 mmapon the file-descriptor returned by shm_open.

考虑使用POSIX通过共享内存shm_openshm_unlink...我个人觉得他们是更容易使用和更直接的比旧的系统V IPC调用如shmget等由于把手返回作品酷似一个文件的描述符,可以用这样的方法调用使用readwrite等等。否则,如果你想访问共享内存对象代表由通过正常指针文件描述符,则可以使用mmap在返回的文件描述符shm_open