UNIX网络编程卷2进程间通信读书笔记(六)—Syst..
时间:2007-04-22 来源:湖光倒影
三、信号灯实例
#include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <errno.h>
union semun{ int val; struct semid_ds *buf; unsigned short int *array; };
void print(int); /*表示共享资源*/ int value; /*用于取得信号灯的值*/ int main(int argc,char **argv) { int n=0; /*用于循环*/ int id; /*信号灯 struct sembuf lock_it; union semun options;
if((id=semget(ftok(argv[1],0),1,IPC_CREAT|IPC_EXCL|0666))==-1) /*创建信号灯*/ perror(“semget”); options.val=3;/*设置信号灯的值*/ semctl(id,0,SETVAL,options);
while(n++<5) { if(fork()==0) /*创建进程*/ { while(1) { lock_it.sem_num=0; lock_it.sem_op=-1; /*信号灯减1*/ lock_it.sem_flg=IPC_NOWAIT;
if((semop(id,&lock_it,1))==-1) { if(errno==EAGAIN) /*如果没有可用的信号灯就继续循环*/ continue; exit(1); } print(id); /*执行表示共享资源的函数*/ lock_it.sem_num=0; lock_it.sem_op=1; /*信号灯加1*/ lock_it.sem_flg=IPC_NOWAIT; if((semop(id,&lock_it,1))==-1) { perror(“semop2”); exit(1); } else { printf(“I’m finished,my pid is %d\n”,getpid()); return; } } } } sleep(3); semctl(id,0,IPC_RMID,0); /*删除一个信号灯*/ exit(0); }
void print(int id) { printf(“I get id,my pid is %d\n”,getpid()); value=semctl(id,0,GETVAL); printf(“now the value have %d\n”,value); sleep(1); } |
主进程循环创建5个子进程,然后使它们去争取值为3的信号灯。没有争到的循环继续争,直到争到为止。
运行结果如下:
#gcc –o sem sem.c
#./sem test
I get it,my pid is 1106
now the value have 2
I get it,my pid is 1107
now the value have 1
I get it,my pid is 1108
now the value have 0
I’m finished,my pid is 1106
I’m finished,my pid is 1107
I’m finished,my pid is 1108
I get it,my pid is 1110
now the value have 2
I get it,my pid is 1109
now the value have 1
I’m finished,my pid is 1110
I’m finished,my pid is 1109