信号量通信设计到的几个函数原型:
int semget(key_t key,int num_sems,int sem_flags); //创建或者获得已经存在的信号量集合,第二个参数表示信号量集合中的信号量个数
semctl(int sem_id, int sem_num,int cmmand,......); //对信号量进行操作,包括初始化,删除信号量
semop(int sem_id,struct sembuf * sem_ops ,size_t num_sem_ops) ; //对信号量进行PV操作
struct sembuf{
unsigned short int sem_num;
short int sem_op;
short int sem_flg; //SEM_UNDO
}
#include<sys/sem.h>
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<fcntl.h>
#include <sys/types.h>
#include <sys/ipc.h>
#define KEY 2345
union semun{
int val;
struct semid_ds* buf;
unsigned short int* array;
};
void PV(int sem_id,int op) //封装PV操作
{
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = op;
sem_b.sem_flg = SEM_UNDO;
int ret;
ret = semop(sem_id,&sem_b,1);
if(ret != 0)
printf("semop failed\n");
}
int main()
{
pid_t pid;
int sem_id = semget((key_t)KEY,1,0666 | IPC_CREAT);
union semun sem_un;
sem_un.val = 1;
semctl(sem_id,0,SETVAL,sem_un); //init sema
if(sem_id < 0)
{
fprintf(stderr,"semget function failed\n");
return 1;
}
pid = fork();
if(pid < 0)
{
fprintf(stderr,"fork function failed\n");
return 1;
}
else if(pid == 0)
{
sleep(2);
fprintf(stdout,"this is child process\n");
fprintf(stdout,"child wait for father V\n");
PV(sem_id,-1); //p
fprintf(stdout,"child do P\n");
fprintf(stdout,"child do V \n"); //V
PV(sem_id,1);
}
else
{
fprintf(stdout,"this is father process\n");
PV(sem_id,-1); //p
fprintf(stdout,"father do P\n");
sleep(10);
fprintf(stdout,"father do V \n"); //V
PV(sem_id,1);
}
waitpid(pid,NULL,0);
semctl(sem_id,0,IPC_RMID,sem_un);
return 0;
}