Sun Microsystems, Inc.
spacerspacer
spacer www.sun.com docs.sun.com |
spacer
black dot
 
 
5.  Interprocess Communication System V IPC System V Semaphores Controlling Semaphores  Previous   Contents   Next 
   
 

Semaphore Operations

semop(2) performs operations on a semaphore set. The semid argument is the semaphore ID returned by a previous semget(2) call. The sops argument is a pointer to an array of structures, each containing the following information about a semaphore operation:

  • The semaphore number

  • The operation to be performed

  • Control flags, if any

The sembuf structure specifies a semaphore operation, as defined in sys/sem.h. The nsops argument specifies the length of the array, the maximum size of which is determined by the SEMOPM configuration option. This option determines the maximum number of operations allowed by a single semop(2) call, and is set to 10 by default.

The operation to be performed is determined as follows:

  • Positive integer increments the semaphore value by that amount.

  • Negative integer decrements the semaphore value by that amount. An attempt to set a semaphore to a value less than zero fails or blocks, depending on whether IPC_NOWAIT is in effect.

  • Value of zero means to wait for the semaphore value to reach zero.

The two control flags that can be used with semop(2) are IPC_NOWAIT and SEM_UNDO.

IPC_NOWAIT

Can be set for any operations in the array. Makes the interface return without changing any semaphore value if it cannot perform any of the operations for which IPC_NOWAIT is set. The interface fails if it tries to decrement a semaphore more than its current value, or tests a nonzero semaphore to be equal to zero.

SEM_UNDO

Allows individual operations in the array to be undone when the process exits.

The following code illustrates semop(2).

#include				<sys/types.h>
#include				<sys/ipc.h>
#include				<sys/sem.h>
...
 	int				i;			/* work area */
 	int				nsops;	/* number of operations to do */
 	int				semid;	/* semid of semaphore set */
 	struct sembuf	*sops;	/* ptr to operations to perform */
 	...
 	if ((i = semop(semid, sops, nsops)) == -1) {
 		perror("semop: semop failed");
 	} else
 		(void) fprintf(stderr, "semop: returned %d\n", i);
 ...

System V Shared Memory

In the SunOS 5.9 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 Management for more information.

The SunOS 5.9 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);
 	...
 
 
 
  Previous   Contents   Next