Chapter Contents

Previous

Next
semget

semget



Create or Find a Set of Semaphores

Portability: UNIX compatible


SYNOPSIS
DESCRIPTION
RETURN VALUE
USAGE NOTES
EXAMPLE
RELATED FUNCTIONS


SYNOPSIS

#include <sys/sem.h>
int semget(key_t key, int num, int flags);


DESCRIPTION

The semget function is used to create a new set of semaphores or to locate an existing set based on a key. Semaphore sets are implemented by UNIX System Services, and allow synchronization of multiple processes which do not share memory. Each semaphore in the set has an integer value, which can be raised, lowered and tested safely by multiple processes. UNIX System Services semaphores allow multiple semaphores to be processed with a single call, and support both blocking and non-blocking processing. Semaphore sets, once created using semget , remain in existence until explicitly destroyed with a call to semctl .

The key argument is an integral value which identifies the semaphore set desired. A key value of IPC_PRIVATE requests a new semaphore set without an associated key , and which can be accessed only by the queue id returned by semget .

The num argument specifies the number of semaphores in the set, if the set is created. If the semaphore set already exists, num must not be larger than the number of semaphores in the set.

Note:   The num argument may be specified as zero if the set already exists, but not for a new set.  [cautionend]
The flags argument specifies zero or more option flags specifying whether or not the semaphore set already exists, and how access to the set should be regulated. The argument should be specified as 0 for no flags, or as one or more of the following symbolic constants, combined using the or operator (|):

Additionally, any of the permission bits S_IRUSR , S_IWUSR , S_IRGRP , S_IWGRP , S_IROTH and S_IWOTH may be specified, to define what users are permitted to access or modify the semaphore set. See the umask function description in the SAS/C Library Reference, Volume 2, for more information about the meaning of these flags.


RETURN VALUE

semget returns the identifier of the semaphore set if successful, or -1 if unsuccessful.


USAGE NOTES

The semget function can only be used with MVS 5.2.2 or a later release.

When semget creates a set of semaphores, the semaphores are uninitialized. You should use the SETALL command of semctl to give the semaphores their initial values.


EXAMPLE

This example is compiled using sascc370 -Krent -o . This program demonstrates the use of the UNIX System Service IPC functions semget() and semstat() .

/*--------------------------------+
| POSIX/UNIX header files         |
+--------------------------------*/
#include <sys/types.h>

#include <unistd.h>

#include <fcntl.h>

#include <sys/ipc.h>

#include <sys/sem.h>

/*--------------------------------+
| ISO/ANSI header files           |
+--------------------------------*/
#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <time.h>

#include errno.h>

/*--------------------------------+
| Types                           |
+--------------------------------*/
/* argument for semctl()            */
typedef union semun               
{
/* for SETVAL                       */
   int  val;                      

/* for IPC_STAT and IPC_SET         */
   struct semid_ds * ID;          

/* for GETALL and SETALL            */
   unsigned short * array;        

} SemaphoreSet;

/*----------------------------------+
| Constants                         |
+----------------------------------*/
/* semaphore key                    */
#define SEM_KEY      (key_t)1097    

/* give everyone read/write         */
/* permission to semaphore          */
#define SEM_PERM  (S_IRUSR|S_IWUSR
  |S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)

/*------------------------------------+
| Name:      main                     |
| Returns:   exit(EXIT_SUCCESS) or    |
|            exit(EXIT_FAILURE)       |
+-------------------------------------*/
int main()
{
/* semaphore set id                   */
    int semID;                  

/* semaphore flags                    */
    int semFlags;               

/* number of semaphore in a set      */
    int numSems;                

/* index into semaphore set (array)   */
    int semNumber;              

/* command to semaphore.              */
    int semCmd;                 

/* union of info on semaphore set     */
    SemaphoreSet semSet;        

/*-----------------------------------------*/
/* Create semaphore set with 5 semaphores. */
/* Give everyone read/write permissions.   */
/*-----------------------------------------*/
/* create set with 5 semaphores    */
   numSems = 5;                    
   semFlags = IPC_CREAT | SEM_PERM;

if ( (semID = semget
  (SEM_KEY, numSems, semFlags)) < 0 )
   {
       perror("SEMSTAT: semget");
       exit(EXIT_FAILURE);
   }

/*-------------------------------------*/
/* Allocate memory to store            */
/* information from semaphore set      */
/*-------------------------------------*/
 semSet.ID = malloc(sizeof(struct semid_ds));

   if (semSet.ID == NULL)
   {
   fprintf(stderr,
   "ERROR: 
   Cannot allocate memory for 
   semaphore set stats\n");
   semctl(semID, NULL, IPC_RMID, NULL);
   exit(EXIT_FAILURE);
   }

/*------------------------------------*/
/* Call semctl to retrieve            */
/* information from semaphore set     */
/*------------------------------------*/
/* command to retrieve stats         */
   semCmd = IPC_STAT;            
/* ignored for IPC_STAT command      */
   semNumber = 0;                

if (semctl(semID, semNumber, 
   semCmd, semSet) < 0)
   {
   perror("SEMSTAT: semctl failed to 
   retrieve semaphore set stats");
   semctl(semID, NULL, IPC_RMID, NULL);
   free(semSet.ID);
   exit(EXIT_FAILURE);
   }
 
/*-----------------------------------*/
/* Print infomation retrieved from   */
/*  semaphore set                    */
/*-----------------------------------*/
 printf("Semaphore Set Statistics:\n\n");

printf("\tOwner's effective user ID: %d\n",
      (int)semSet.ID->sem_perm.uid);
printf("\tOwner's effective group ID: %d\n",
      (int)semSet.ID->sem_perm.gid);
printf("\tCreator's effective user ID: %d\n",
      (int)semSet.ID->sem_perm.cuid);
printf("\tCreator's effective group ID: %d\n",
      (int)semSet.ID->sem_perm.cgid);
printf("\tPermission mode bits: %#.3o\n\n",
      (int)semSet.ID->sem_perm.mode);

printf("\tNumber of semaphores currently in 
   the set: %d\n",
      semSet.ID->sem_nsems);
printf("\tTime of last semop call: %s",
      ctime(&semSet,ID->sem_otime));
printf("\tTime of last change: %s",
      ctime(&semSet.ID->sem_ctime));

/*--------------------------------------*/
/* Free memory used to store            */
/* information from semaphore set       */
 *--------------------------------------*/
   free(semSet.ID);

/*---------------------------------------*/
/* Call semctl to remove semaphore set.  */
/*---------------------------------------*/
if (semctl(semID, NULL, IPC_RMID, NULL) < 0)
   {
   perror("SEMSTAT: semctl failed to 
   remove semNumber set");
   exit(EXIT_FAILURE);
   }
 
   exit(EXIT_SUCCESS);

}  /* end of main() */


RELATED FUNCTIONS

semctl , semop


Chapter Contents

Previous

Next

Top of Page

Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.