以下是一个system V的信号量同步例子,共5个进程,P1,P2,P3,P4,P5。同步关系是P1最先执行;P2、P3、P4都是等待P1完成之后才能执行,P5等待P2,P3,P4全部完成之后才能执行。
#include <stdio.h> #include <sys/sem.h> #include <sys/ipc.h> #include <sys/types.h> #define KEY1 1211 #define KEY2 1212 #define KEY3 1213 #define KEY4 1214 #define KEY5 1215 #define KEY6 1216 union semun{ int val; struct semid_ds *buf; unsigned short *array; }; int crt_sem(key_t key, int val) { union semun arg; int id = semget(key, 1, IPC_CREAT); arg.val = val; semctl(id, 0, SETVAL, arg); return id; } void P(int semid) { struct sembuf p[1]; p[0].sem_num = 0; p[0].sem_op = -1; p[0].sem_flg = 0; semop(semid, p, 1); } void V(int semid) { struct sembuf v[1]; v[0].sem_num = 0; v[0].sem_op = 1; v[0].sem_flg = 0; semop(semid, v, 1); } int main(void) { int i = 1; pid_t pid; int t; int p12 = crt_sem(KEY1, 0); t = semctl(p12, 0, GETVAL); printf("init value of p12 is %d./n"); int p13 = crt_sem(KEY2, 0); t = semctl(p13, 0, GETVAL); printf("init value of p13 is %d./n"); int p14 = crt_sem(KEY3, 0); t = semctl(p14, 0, GETVAL); printf("init value of p14 is %d./n"); int p25 = crt_sem(KEY4, 0); t = semctl(p25, 0, GETVAL); printf("init value of p25 is %d./n"); int p35 = crt_sem(KEY5, 0); t = semctl(p35, 0, GETVAL); printf("init value of p35 is %d./n"); int p45 = crt_sem(KEY6, 0); t = semctl(p45, 0, GETVAL); printf("init value of p45 is %d./n"); while (i < 6){ if ((pid = fork()) < 0){ printf("process fork error./n"); return(0); }else if(pid == 0){ break; }else{ i++; } } if (i == 1){ sleep(1); printf("----------------process1./n"); //printf("-----------before:%d/n",semctl(p12,0,GETVAL,0)); V(p12); V(p13); V(p14); printf("p12 after process1:%d/n",semctl(p12,0,GETVAL,0)); printf("p13 after process1:%d/n",semctl(p13,0,GETVAL,0)); printf("p14 after process1:%d/n",semctl(p14,0,GETVAL,0)); } if (i == 2){ sleep(2); P(p12); t = semctl(p12, 0, GETVAL, 0); printf("--------------process2./n"); V(p25); printf("p12 after process2:%d/n",semctl(p12,0,GETVAL,0)); printf("p25 after process2:%d/n",semctl(p25,0,GETVAL,0)); } if (i == 3){ sleep(2); P(p13); printf("--------------process3./n"); V(p35); printf("p13 after process3:%d/n",semctl(p13,0,GETVAL,0)); printf("p35 after process3:%d/n",semctl(p35,0,GETVAL,0)); } if (i == 4){ sleep(2); P(p14); printf("--------------process4./n"); V(p45); printf("p14 after process4:%d/n",semctl(p14,0,GETVAL,0)); printf("p45 after process4:%d/n",semctl(p45,0,GETVAL,0)); } if (i == 5){ sleep(4); P(p25); P(p35); P(p45); printf("--------------process5./n"); printf("p25 after process5:%d/n",semctl(p25,0,GETVAL,0)); printf("p35 after process5:%d/n",semctl(p35,0,GETVAL,0)); printf("p45 after process5:%d/n",semctl(p45,0,GETVAL,0)); } if (i == 6) sleep(5); return(0); } |
|