Oracle® Solaris 11.2 Programming Interfaces Guide

Exit Print View

Updated: July 2014
 
 

System V Shared Memory

In the SunOS 5.11 operating system, the most efficient way to implement shared memory applications is to rely on mmap(2) and on the system's native virtual memory facility. See Chapter 1, Memory and CPU Management for more information.

The SunOS 5.11 platform also supports System V shared memory, which is a less efficient way to enable the attachment of a segment of physical memory to the virtual address spaces of multiple processes. When write access is allowed for more than one process, an outside protocol or mechanism, such as a semaphore, can be used to prevent inconsistencies and collisions.

A process creates a shared memory segment using shmget(2). This call is also used to get the ID of an existing shared segment. The creating process sets the permissions and the size in bytes for the segment.

The original owner of a shared memory segment can assign ownership to another user with shmctl(2). The owner can also revoke this assignment. Other processes with proper permission can perform various control functions on the shared memory segment using shmctl(2).

Once created, you can attach a shared segment to a process address space using shmat(2). You can detach it using shmdt(2). The attaching process must have the appropriate permissions for shmat(2). Once attached, the process can read or write to the segment, as allowed by the permission requested in the attach operation. A shared segment can be attached multiple times by the same process.

A shared memory segment is described by a control structure with a unique ID that points to an area of physical memory. The identifier of the segment is called the shmid. The structure definition for the shared memory segment control structure can be found in sys/shm.h.

Accessing a Shared Memory Segment

shmget(2) is used to obtain access to a shared memory segment. When the call succeeds, it returns the shared memory segment ID (shmid). The following code illustrates shmget(2).

#include                     <sys/types.h>
#include                     <sys/ipc.h>
#include                     <sys/shm.h>
...
        key_t     key;       /* key to be passed to shmget() */
        int       shmflg;    /* shmflg to be passed to shmget() */
        int       shmid;     /* return value from shmget() */
        size_t    size;      /* size to be passed to shmget() */
        ...
        key = ...
        size = ...
        shmflg) = ...
        if ((shmid = shmget (key, size, shmflg)) == –1) {
               perror("shmget: shmget failed");
               exit(1);
        } else {
               (void) fprintf(stderr,
                             "shmget: shmget returned %d\n", shmid);
               exit(0);
        }
...

Controlling a Shared Memory Segment

shmctl(2) is used to alter the permissions and other characteristics of a shared memory segment. The cmd argument is one of following control commands.

SHM_LOCK

Lock the specified shared memory segment in memory. The process must have the effective ID of superuser to perform this command.

SHM_UNLOCK

Unlock the shared memory segment. The process must have the effective ID of superuser to perform this command.

IPC_STAT

Return the status information contained in the control structure and place it in the buffer pointed to by buf. The process must have read permission on the segment to perform this command.

IPC_SET

Set the effective user and group identification and access permissions. The process must have an effective ID of owner, creator or superuser to perform this command.

IPC_RMID

Remove the shared memory segment. The process must have an effective ID of owner, creator, or superuser to perform this command.

The following code illustrates shmctl(2).

#include                     <sys/types.h>
#include                     <sys/ipc.h>
#include                     <sys/shm.h>
...
int     cmd;                 /* command code for shmctl() */
int     shmid;               /* segment ID */
struct  shmid_ds  shmid_ds;  /* shared memory data structure to hold results */
        ...
        shmid = ...
        cmd = ...
        if ((rtrn = shmctl(shmid, cmd, shmid_ds)) == –1) {
                perror("shmctl: shmctl failed");
                exit(1);
...

Attaching and Detaching a Shared Memory Segment

shmat() and shmdt() are used to attach and detach shared memory segments (see the shmop(2) man page). shmat(2) returns a pointer to the head of the shared segment. shmdt(2) detaches the shared memory segment located at the address indicated by shmaddr. The following code illustrates calls to shmat(2) and shmdt(2)

#include              <sys/types.h>
#include              <sys/ipc.h>
#include              <sys/shm.h>

static struct state { /* Internal record of attached segments. */
        int           shmid;        /* shmid of attached segment */
        char          *shmaddr;     /* attach point */
        int           shmflg;       /* flags used on attach */
} ap[MAXnap];                       /* State of current attached segments. */
int     nap;                        /* Number of currently attached segments. */
...
char    *addr;                      /* address work variable */
register int          i;            /* work area */
register struct state *p;           /* ptr to current state entry */
...
        p = &ap[nap++];
        p–>shmid = ...
        p–>shmaddr = ...
        p–>shmflg = ...
        p–>shmaddr = shmat(p->shmid, p->shmaddr, p->shmflg);
        if(p–>shmaddr == (char *)-1) {
                perror("shmat failed");
                nap–-;
        } else
                (void) fprintf(stderr, "shmop: shmat returned %p\n",
                                    p–>shmaddr);
        ...
        i = shmdt(addr);
        if(i == –1) {
                 perror("shmdt failed");
        } else {
                 (void) fprintf(stderr, "shmop: shmdt returned %d\n", i);
                 for (p = ap, i = nap; i–-; p++) {
                         if (p–>shmaddr == addr) *p = ap[–-nap];
                 }
        }
...