Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sharing same variable between more than one independent programs in Linux [closed]

Tags:

c

linux

ipc

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.

like image 883
Rifat Rousseau Avatar asked May 21 '12 11:05

Rifat Rousseau


People also ask

Do forked processes share global variables?

No, since global variables are not shared between processes unless some IPC mechanism is implemented. The memory space will be copied. As a consequence, the global variable in both processes will have the same value inmediately after fork, but if one changes it, the other wont see it changed.

Do parent and child process share the variables?

What is shared between forked processes? Answer: Only the shared memory segments are shared between the parent process and the newly forked child process. Copies of the stack and the heap are made for the newly created process.

Does fork shared memory?

Threads. While fork copies all of the attributes we mentioned above, imagine if everything was copied for the new process except for the memory. This means the parent and child share the same memory, which includes program code and data. Separate processes can not see each others memory.


2 Answers

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:

  • (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).

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).

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).


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

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.

  • shm_open - to get shared memory (via file descriptor)
  • ftruncate - to set the size of the shared memory
  • mmap - to get a pointer to the memory
  • sem_open - to get a semaphore
  • sem_wait, sem_post - for your read/write synchronisation
  • shm_unlink, sem_close - to clean up after all

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)


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.).

like image 147
moooeeeep Avatar answered Nov 07 '22 22:11

moooeeeep


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.

like image 6
Jason Avatar answered Nov 07 '22 21:11

Jason