Shared Memory
Shared memory allows two or more processes to share a given region of memory. This is the fastest form of IPC, because the data does not need to be copied between the client and the server. The only trick in using shared memory is synchronizing access to a given region among multiple processes. If the server is placing data into a shared memory region, the client shouldn’t try to access the data until the server is done. Often, semaphores are used to synchronize shared memory access.
The Single UNIX Specification shared memory objects option includes alternative interfaces, originally real-time extensions, to access shared memory.
The kernel maintains a structure with at least the following members for each shared memory segment:
struct shmid_ds {
struct ipc_perm shm_perm; /* see Section 15.6.2 */
size_t shm_segsz; /* size of segment in bytes */
pid_t shm_lpid; /* pid of last shmop() */
pid_t shm_cpid; /* pid of creator */
shmatt_t shm_nattch; /* number of current attaches */
time_t shm_atime; /* last-attach time */
time_t shm_dtime; /* last-detach time */
time_t shm_ctime; /* last-change time */
...
};
(Implementations add other structure members to support shared memory segments.)
The first function called is usually shmget, to obtain a shared memory identifier.
#include <sys/shm.h>
int shmget(key_t key, size_t size, int flag);
When a new segment is created, the following members of the shmid_ds structure are initialized.
- The ipc_perm structure is initialized as described in Section 15.6.2. The mode member of this structure is set to the corresponding permission bits of flag. These permissions are specified with the values from Figure 15.24.
- shm_lpid, shm_nattch, shm_atime, and shm_dtime are all set to 0.
- shm_ctime is set to the current time.
- shm_segsz is set to the size requested.
The size parameter is the size of the shared memory segment in bytes.
The shmctl function is the catchall for various shared memory operations.
#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf );
The cmd argument specifies one of the following five commands to be performed, on the segment specified by shmid.
IPC_STAT
Fetch the shmid_ds structure for this segment, storing it in the structure pointed to by buf.
IPC_SET
Set the following three fields from the structure pointed to by buf in the shmid_ds structure associated with this shared memory segment: shm_perm.uid, shm_perm.gid, and shm_perm.mode. This command can be executed only by a process whose effective user ID equals shm_perm.cuid or shm_perm.uid or by a process with superuser privileges.
IPC_RMID
Remove the shared memory segment set from the system. Since an attachment count is maintained for shared memory segments (the shm_nattch field in the shmid_ds structure), the segment is not removed until the last process using the segment terminates or detaches it. Regardless of whether the segment is still in use, the segment’s identifier is immediately removed so that shmat can no longer attach the segment.
Two additional commands are provided by Linux and Solaris, but are not part of the Single UNIX Specification.
SHM_LOCK
Lock the shared memory segment in memory. This command can be executed only by the superuser.
SHM_UNLOCK
Unlock the shared memory segment. This command can be executed only by the superuser.
Once a shared memory segment has been created, a process attaches it to its address space by calling shmat.
#include <sys/shm.h>
void *shmat(int shmid, const void *addr, int flag);