信号量的接口以及单个信号量的例子见此博客
多个信号量
三个进程a,b,c分别输出"A","B","C",要求输出的结果必须是”ABCABCABC...“;
思路:
代码演示:
//sem.h
typedef union senum
{
int val;
}SemUn;
int GetSem(int key,int initval[],int n);
int DelSem(int semid);
int SemP(int semid,int index);
int SemV(int semid,int index);
//sem.c
#include "sem.h"
#include <sys/sem.h>
#include <stdio.h>
int GetSem(int key,int initval[],int n)
{
int semid=semget((key_t)key,n,0600|IPC_CREAT|IPC_EXCL);
if(semid==-1)
{
semid=semget((key_t)key,n,0600);
if(semid==-1)
{
printf("semget error!\n");
return -1;
}
}
else
{
int i=0;
for(;i<n;i++)
{
SemUn data;
data.val=initval[i];
int res=semctl(semid,i,SETVAL,data);
if(res==-1)
{
printf("semcil error");
DelSem(semid);
return -1;
}
}
}
return semid;
}
int SemP(int semid,int index)
{
struct sembuf buf;
buf.sem_num=index;//第几个信号量S1,S2,S3
buf.sem_op=-1;
buf.sem_flg=SEM_UNDO;
int res=semop(semid,&buf,1);
if(res==-1)
{
printf("semop p error!\n");
return -1;
}
return 0;
}
int SemV(int semid,int index)
{
struct sembuf buf;
buf.sem_num=index;//第几个信号量S1,S2,S3
buf.sem_op=1;
buf.sem_flg=SEM_UNDO;
int res=semop(semid,&buf,1);
if(res==-1)
{
printf("semop v error!\n");
return -1;
}
return 0;
}
int DelSem(int semid)
{
if(semctl(semid,0,IPC_RMID)==-1)
{
perror("semctl del error!\n");
return -1;
}
return 0;
}
//a.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <unistd.h>
#include "sem.h"
int main()
{
srand(time(NULL));
int initval[]={1,0,0};
int semid=GetSem(1234,initval,3);
assert(semid!=-1);
int count=0;
while(count<5)
{
SemP(semid,0);
printf("A");
fflush(stdout);
int n=rand()%3;
sleep(n);
SemV(semid,1);
count++;
}
exit(0);
}
//b.c
include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <unistd.h>
#include "sem.h"
int main()
{
srand(time(NULL));
int initval[]={1,0,0};
int semid=GetSem(1234,initval,3);
assert(semid!=-1);
int count=0;
while(count<5)
{
SemP(semid,1);
printf("B");
fflush(stdout);
int n=rand()%3;
sleep(n);
SemV(semid,2);
count++;
}
exit(0);
}
//c.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <unistd.h>
#include "sem.h"
int main()
{
srand(time(NULL));
int initval[]={1,0,0};
int semid=GetSem(1234,initval,3);
assert(semid!=-1);
int count=0;
while(count<5)
{
SemP(semid,2);
printf("C");
fflush(stdout);
int n=rand()%3;
sleep(n);
SemV(semid,0);
count++;
}
DelSem(semid);//最后一个退出的销毁
exit(0);
}
运行结果: