Search code examples
clinuxsysv-ipc

Detaching from shared memory before removing it


When I have several processes going on using a shared memory, and I detach all of them but one.

  1. Does it make sense to detach the last process before removing the shared memory with shmctl() (with that process)?
  2. If it doesn't make sense, is it possible to remove the shared memory after detaching from it?

Solution

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