生产者消费者模型的实现

#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
#===================================================#



 

转载于:https://www.cnblogs.com/cise/p/5281326.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值