The manual entry for shmctl()
doesn't say anything about 'at most one process using it' or 'no processes attached to it'. However, the system can't completely disrupt already running processes that are attached to the shared memory segment.
You only need the shmid
(shared memory segment ID) returned by shmget()
; you don't need the shared memory to be attached (so you could already have run shmdt()
).
Testing on a Mac (macOS Sierra 10.12.3, GCC 6.3.0) with code derived from a previous question (Making a shared data structure in C), I added an option -t time
to make the process sleep for a specifiable period. Then I created a shared memory segment and left the process holding it open. I used ipcs -m
to see that the segment existed. Then I deleted the segment; it was successful. Rechecking with ipcs -m
, the segment had changed from shared to IPC_PRIVATE
. When the sleeping process completed, the shared memory segment was automatically deleted (as private segments always are).
$ shm-master -f shm-master -s 1024 -x -t 120 &
[1] 14392
$ ID: 0, File: shm-master
Key: 0x00041BF7
ShmID: 1441795
Shared memory allocated at 0x10F2B4000
Sleeping for 120 seconds
$ ipcs -m
IPC status from <running system> as of Wed Feb 15 11:56:37 PST 2017
T ID KEY MODE OWNER GROUP
Shared Memory:
m 65536 0x00fedc64 --rw-rw-rw- root wheel
m 65537 0x0052e2c1 --rw------- postgres daemon
m 65538 0x52042973 --rw------- root wheel
m 1441795 0x00041bf7 --rw------- jleffler staff
$ shm-master -f shm-master -s 1024 -d
ID: 0, File: shm-master
Key: 0x00041BF7
ShmID: 1441795
Shared memory removed
$ ipcs -m
IPC status from <running system> as of Wed Feb 15 11:56:47 PST 2017
T ID KEY MODE OWNER GROUP
Shared Memory:
m 65536 0x00fedc64 --rw-rw-rw- root wheel
m 65537 0x0052e2c1 --rw------- postgres daemon
m 65538 0x52042973 --rw------- root wheel
m 1441795 0x00000000 --rw------- jleffler staff
$ sleep 120; ipcs -m
Detached from shared memory
[1]+ Done shm-master -f shm-master -s 1024 -x -t 120
IPC status from <running system> as of Wed Feb 15 11:58:57 PST 2017
T ID KEY MODE OWNER GROUP
Shared Memory:
m 65536 0x00fedc64 --rw-rw-rw- root wheel
m 65537 0x0052e2c1 --rw------- postgres daemon
m 65538 0x52042973 --rw------- root wheel
$
Whether this is what happens on other systems, I'm not sure, but it looks like plausible behaviour. Something similar is likely to occur.
Incidentally, running one process to create the segment and a second to just attach to it, both running in sleep mode, didn't really change the observed results. The shared memory segment key changed to 0, the processes were unaffected, and the segment was deleted after both had completed.