以下是一个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);
}