Key C functions:ide
int shmid = shmget(key_t key, size_t size, int shmflg); // Create an identifier for the shared mem segment by key void *shmat(int shmid, const void *shmaddr, int shmflg); // attach int shmdt(const void *shmaddr); // detach; only the address to the mem is needed here int shmctl(int shmid, int cmd, struct shmid_ds *buf); // perform some operation on the mem segment
Code snippet:ui
#include <sys/ipc.h> #include <sys/shm.h> # define SHM_SHARED_KEY 8999 key_t key = SHM_SHARED_KEY; //int shmget(key_t key, size_t size, int shmflg); int shmid = shmget(key, sizeof( int ), IPC_CREAT | /*IPC_EXCL |*/ 0660 ); /* IPC_CREAT Creat a new segment; if not set, shmget() check the segment associated with key and check if the user has permission to access it. IPC_EXCL used with IPC_CREAT to ensure this call creates the segment. If the segment already exists, the call fails. ... When a new shared memory segment is created, its contents are initialized to zero values, ... Return a memory identifier on success; -1 on error */ /* Attach to the shared memory segment */ // void *shmat(int shmid, const void *shmaddr, int shmflg); int * data = shmat( shmid, NULL, 0 ); /* Notice that 'void *' means returning a pointer which can be used to point to any type of data */ /* shmat() attaches the System V shared memory segment identi‐ fied by shmid to the address space of the calling process. The attaching address is specified by shmaddr with one of the following criteria: * If shmaddr is NULL, the system chooses a suitable (unused) page-aligned address to attach the segment. * If shmaddr isn't NULL and SHM_RND is specified in shmflg, the attach occurs at the address equal to shmaddr rounded down to the nearest multiple of SHMLBA. * Otherwise, shmaddr must be a page-aligned address at which the attach occurs. shmat() returns the address of the attached shared memory segment; on error, (void *) -1 is returned */ /* Detach from the shared memory segment*/ //int shmdt(const void *shmaddr); int rc = shmdt( data ); /* Detach from the shared mem segment specified by address shmaddr On success, shmdt() returns 0; on error -1 is returned, */ /* Perform some operation specified by cmd on the shared memoey segment identified by shimid */ /* int shmctl(int shmid, int cmd, struct shmid_ds *buf);*/ int rc = shmctl( shmid, IPC_RMID, 0 ); /* In this case, destroy the mem segment identified by shmid; If not destroy it, this mem segment will still be accessible from other processes. (i.e. when re-run this programme, the old data still exists) IPC_RMID Mark the segment to be destroyed. The segment will actually be destroyed only after the last process detaches it. The caller must be the owner or creator of the segment, or be privileged. The buf argument is ignored. */
Notes:this
If a shared memory segment is not destroyed (i.e. using shmctl( shmid, IPC_RMID, 0 )
), it will still be accessible from other processes if given the same key. (Q: Thus within the period key -> shmid is some motonous function?); when it is destroyed, using shmget(key, **argv) will map to a different identifier shmid.spa
When a parent process attachs to a shared mem segment (before fork), its child processes will also attach to that mem segment.rest
When calling destroy to a shared mem segment, it will only be destroyed after the last process attached to it detached from it.code
A destroy call can only be made from the owner or creator of the mem segment.orm