如果 sem_op 是一个负整数,并且信号量的值小于 sem_op 的绝对值,则在 IPC_NOWAIT 为 true 时立即停止测试的执行,而在该值为 false 时则阻塞,直至信号量的值变得大于 sem_op 的绝对值。
清单 5 中的示例阐明了信号量的使用,其中研究了一个可同时运行多次的程序,但是该程序确保一次只有一个进程处于关键部分。其中使用了简单情况下的信号量;当信号量的值为 0 时释放资源。
清单 5. 使用信号量来保护关键部分
#include <sys/types.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <string.h> /* For strerror(3c) */
#include <errno.h> /* For errno */
#include <unistd.h> /* rand(3c) */
#include <stdio.h>
int main (int argc, char **argv) {
key_t ipckey;
int semid;
struct sembuf sem[2]; /* sembuf defined in sys/sem.h */
/* Generate the ipc key */
ipckey = ftok("/tmp/foo", 42);
/* Set up the semaphore set. 4 == READ, 2 == ALTER */
semid = semget(ipckey, 1, 0666 | IPC_CREAT);
if (semid < 0) {
printf("Error - %sn", strerror(errno));
_exit(1);
}
/* These never change so leave them outside the loop */
sem[0].sem_num = 0;
sem[1].sem_num = 0;
sem[0].sem_flg = SEM_UNDO; /* Release semaphore on exit */
sem[1].sem_flg = SEM_UNDO; /* Release semaphore on exit */
while(1) { /* loop forever */
printf("[%s] Waiting for the semaphore to be releasedn", argv[1]);
/* Set up two semaphore operations */
sem[0].sem_op = 0; /* Wait for zero */
sem[1].sem_op = 1; /* Add 1 to lock it*/
semop(semid, sem, 2);
printf("[%s] I have the semaphoren", argv[1]);
sleep(rand() % 3); /* Critical section, sleep for 0-2 seconds */
sem[0].sem_op = -1; /* Decrement to unlock */
semop(semid, sem, 1);
printf("[%s] Released semaphoren", argv[1]);
sleep(rand() % 3); /* Sleep 0-2 seconds */
}
}
标签: