/* Unix semaphore library */ #include #include #include #include /* The semaphore key is an arbitrary long integer which serves as an external identifier by which the semaphore is known to any program that wishes to use it. */ #define KEY (1492) /*initialize a semaphore. Return the id of the semaphore*/ int initializeSemaphore (long key, int value) { int id; /* Number by which the semaphore is known within a program */ /* The next thing is an argument to the semctl() function. Semctl() does various things to the semaphore depending on which arguments are passed. We will use it to make sure that the value of the semaphore is initially 0. */ union semun { int val; struct semid_ds *buf; ushort * array; } argument; argument.val = value; /* Create the semaphore with external key key if it doesn't already exists. Give permissions to the world. */ id = semget(key, 1, 0666 | IPC_CREAT); /* Always check system returns. */ if(id < 0) { fprintf(stderr, "Unable to obtain semaphore.\n"); return id; } /* What we actually get is an array of semaphores. The second argument to semget() was the array dimension - in our case 1. */ /* Set the value of the number 0 semaphore in semaphore array #id to the value 0. */ if( semctl(id, 0, SETVAL, argument) < 0) fprintf( stderr, "Cannot set semaphore value.\n"); else fprintf(stderr, "Semaphore %ld initialized at %d.\n", key, argument.val); return id; } int increaseSemaphore(int id) { struct sembuf operations[1]; /* An "array" of one operation to perform on the semaphore. */ int retval; /* Return value from semop() */ /* Set up the sembuf structure. */ /* Which semaphore in the semaphore array : */ operations[0].sem_num = 0; /* Which operation? Add 1 to semaphore value : */ operations[0].sem_op = 1; /* Set the flag so we will wait : */ operations[0].sem_flg = 0; /* So do the operation! */ retval = semop(id, operations, 1); if(retval != 0) printf("semaphore increase operation did not succeed.\n"); return retval; } int increaseSemaphoreByKey(long key) { /* Get the index for the semaphore with external name key. */ int id = semget(key, 1, 0666); if(id < 0) { /* Semaphore does not exist. */ fprintf(stderr, "Program sema cannot find semaphore, exiting.\n"); return id; } return increaseSemaphore(id); } int decreaseSemaphore(int id) { struct sembuf operations[1]; /* An "array" of one operation to perform on the semaphore. */ int retval; /* Return value from semop() */ if(id < 0) { /* Semaphore does not exist. */ fprintf(stderr, "Program semb cannot find semaphore, exiting.\n"); return -1; } /* Set up the sembuf structure. */ /* Which semaphore in the semaphore array : */ operations[0].sem_num = 0; /* Which operation? Subtract 1 from semaphore value : */ operations[0].sem_op = -1; /* Set the flag so we will wait : */ operations[0].sem_flg = 0; /* So do the operation! */ retval = semop(id, operations, 1); if(retval != 0) fprintf(stderr,"semaphore decrease operation did not succeed.\n"); return retval; } int decreaseSemaphoreByKey(long key) { /* Get the index for the semaphore with external name key. */ int id = semget(key, 1, 0666); if(id < 0) { /* Semaphore does not exist. */ fprintf(stderr, "Program sema cannot find semaphore, exiting.\n"); return id; } return decreaseSemaphore(id); }