#include "semInc.h"
int main()
{
int semid1=-1,semid2=-1,semMutex=-1;
//定义两个信号的引用标识符
semid1 = semget(SEM_KEY1,1,IPC_CREAT|0660);
semid2 = semget(SEM_KEY2,1,IPC_CREAT|0660);
semMutex = semget(SEM_MUTEX,1,IPC_CREAT|0660);
if (semid1<0||semid2<0||semMutex<0)
oops("semget");
int i=0;
while(1)
{
i=i+1;
p_semaphore(semid2,0,1);
p_semaphore(semMutex,0,1);
printf("%-d\t:thello world\n",i);
//sleep(1);
v_semaphore(semid1,0,1);
v_semaphore(semMutex,0,1);
}
//生产者开始生产
//销毁信号量集合
}
具体原理请看《计算机操作系统》,原理就不再多说了,下面直接给出源码。
semInc.h,这个头文件实现了PV操作
//=====================all header===================//
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#include <stdlib.h>
//======================宏定义===============================//
#define SEM_KEY1 1492
#define SEM_KEY2 1493
#define SEM_MUTEX 1494
#define oops(var) {fprintf(stderr,var);printf("\n");exit(1);}
//================定义函数===========================//
void init_semaphore(int sid,int semnum,int initval);// 初始化信号量
void p_semaphore(int sid,int semnum,int n);//p 操作
void v_semaphore(int sid,int semnum,int n);//v 操作
void kill_semaphore(int sid);//销毁信号量集合
//======================定义参数数据结构=======================//
union semun
{
int val;/*value for SETVAL*/
struct semid_ds *buf;/*buffer for IPC_STAT&IPC_SET*/
ushort *array;/*array for GETALL&SETALL*/
};
//===============初始化信号量集中的某个信号的函数================//
/*
initialization the semaphore
初始化信号量
*/
void init_semaphore(int sid,int semnum,int initval)
{
union semun semopts;
semopts.val=initval;
semctl(sid,semnum,SETVAL,semopts);
}
/*
p_semaphore
wait(n),that is sem.semval = sem.semval -n;
P 操作
*/
void p_semaphore(int sid,int semnum,int n)
{
n=n*(-1);
struct sembuf buf={semnum,n,0};//semoarrary[1];
semop(sid,&buf,1);
}
/*
single(n),that is sem.semval=sem.semval+n;
V 操作
*/
void v_semaphore(int sid,int semnum,int n)
{
struct sembuf buf={semnum,n,0};//semoarrary[1];
semop(sid,&buf,1);
}
/*
销毁信号量,把志愿还给系统。
*/
void kill_semaphore(int sid)
{
if(semctl(sid,IPC_RMID,0) < 0)
oops("semctl:kill_semaphore\n");
}
productor.c生成者代码:
#include "semInc.h"
int main()
{
int semid1=-1,semid2=-1,semMutex=-1;
//定义两个信号的引用标识符
semid1 = semget(SEM_KEY1,1,IPC_CREAT|0660);
semid2 = semget(SEM_KEY2,1,IPC_CREAT|0660);
semMutex = semget(SEM_MUTEX,1,IPC_CREAT|0660);
if (semid1<0||semid2<0||semMutex<0)
oops("semget");
//creat 3 semphore,contain 1
init_semaphore(semid1,0,18);
init_semaphore(semid2,0,0);
init_semaphore(semMutex,0,1);
//初始化信号量值为10、和0
int i=0;
//kill_semaphore(semid1,0);
while(1)
{
sleep(1);
i=i+1;
p_semaphore(semid1,0,1);
p_semaphore(semMutex,0,1);
printf("%-d\t:thello world\n",i);
v_semaphore(semid2,0,1);
v_semaphore(semMutex,0,1);
}
return 0;
}
消费者代码:consumer.c
#include "semInc.h"
int main()
{
int semid1=-1,semid2=-1,semMutex=-1;
//定义两个信号的引用标识符
semid1 = semget(SEM_KEY1,1,IPC_CREAT|0660);
semid2 = semget(SEM_KEY2,1,IPC_CREAT|0660);
semMutex = semget(SEM_MUTEX,1,IPC_CREAT|0660);
if (semid1<0||semid2<0||semMutex<0)
oops("semget");
int i=0;
while(1)
{
i=i+1;
p_semaphore(semid2,0,1);
p_semaphore(semMutex,0,1);
printf("%-d\t:thello world\n",i);
//sleep(1);
v_semaphore(semid1,0,1);
v_semaphore(semMutex,0,1);
}
}
makefile
#====================编译消费者======================#
consumer: consumer.o
cc -o consumer consumer.o
consumer.o:consumer.c semInc.h
cc -c consumer.c
#====================编译生产者======================#
productor: productor.o
cc -o productor productor.o
productor.o:productor.c semInc.h
cc -c productor.c
#====================结尾工作=========================#
.PHONY:clean
clean:
rm *.o
#================================================#
.PHONY:all
all:
make consumer
make productor
rm *.o
#===================================================#