I'm trying to synchronize and make a few threads/processes communicate for a project and I'd ideally like to access some shared memory blocks between them, without having them clash with other processes/resources.
I know IPC_PRIVATE will generate a unique key when calling shmget()
to create it, but if I then need that key to open that region somewhere in other processes, how can I access that generated key_t
value so that I can send it to the other process?
I'm currenty sending data through IPC message-queues, and so I can send the shmid value, but as far as I know that doesn't work since the shmid value is unique for each process.
Do I have no other options but try luck with ftok()
and some random files? Do I have to choose a different file for each block of different shared memory I wish to create?
Thank you for your time.
I know IPC_PRIVATE will generate a unique key when calling shmget() to create it
No, you misunderstand. IPC_PRIVATE
does not generate a key_t
, it is a key_t
. This special key_t
elicits the special behavior from shmget()
of always creating a new segment, ignoring all bits of the flags except the mode bits.
if I then need that key to open that region somewhere in other processes, how can I access that generated key_t value so that I can send it to the other process?
Since you always get a new segment with IPC_PRIVATE
, you cannot share memory between processes by each one independently obtaining a shared-memory segment via that key. Instead, for two or more processes to communicate via such a segment, (inserted 2021-12-19) they may exchange the shmid that one of them obtains from shmget()
, or they must may all have inherited it from a common ancestor process that created it (or be the process that created it). Processes that do not have such a relationship with each other cannot use the IPC_PRIVATE
key to access the same segment.
Do I have no other options but try luck with ftok() and some random files? Do I have to choose a different file for each block of different shared memory I wish to create?
Since you're using System-V shared memory, you do have the alternative of using ftok()
to generate keys based on an existing path, but it doesn't have to be an arbitrary file. You can use the path to a file that is characteristic of the particular group of cooperating processes -- an input file, a working directory, or similar. Moreover, ftok()
also uses an integer "project id" with which you can discriminate between unrelated runs, or between multiple distinct keys serving different purpose, or similar. You could choose some designated process's process id there if you have no other good way to discriminate.
Do note, by the way, that the System-V IPC interfaces are pretty clunky. They do have a couple of distinguishing features that may occasionally make them preferable, but the newer POSIX interfaces (shm_open()
, etc.) are usually the better choice. The POSIX versions don't offer a particularly better solution to the problem you've asked about, however.