模拟生产者/消费者模型

本文详细阐述了使用信号量和共享内存实现生产者消费者模型的方法,包括信号量的创建、初始化、操作及与共享内存的交互过程,通过实例展示了如何在并发环境中确保资源的正确分配与使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
** 模拟生产者/消费者模型
** 模拟过程:
** 生产者 消费者
**
** P(上限控制旗语) P(下限控制旗语)
** P(仓库互斥访问旗语)
** 添加产品 消费产品
** V(仓库互斥访问旗语)
** V(下限控制旗语) V(上限控制旗语)
**
*/


#include <stdio.h>
#include <sys/types.h>//类型
#include <sys/sem.h>//信号量
#include <string>//
#include <sys/mman.h>//
#include <sys/shm.h>


#define SEM_NUMBER 3  //信号量的数目
#define MAX_SEM 0 //上限控制旗语 
#define MIN_SEM 1 //下限控制旗语
#define BIN_SEM 2 //仓库互斥访问旗语
#define MAX_PRODUCT 20 //最大产品数量


int main(int argc, char *argv[])
{
key_t key,key1;
int shmid,semid;
int *pProduct;//产品个数


struct sembuf lockMax = {0,-1,0};
struct sembuf unlockMax = {0,1,0};
struct sembuf lockMin = {1,-1,0};
struct sembuf unlockMin = {1,1,0};
struct sembuf lockBin = {2,-1,0};
struct sembuf unlockBin = {2,1,0};


key = ftok(__FILE__,1);
key1 = ftok(__FILE__,2);

//创建共享内存
shmid = shmget(key,1024,IPC_CREAT|0666);
if(shmid < 0)
{
perror("shmget");
exit(EXIT_FAILURE);
}


//指向共享内存
pProduct = (int *)shmat(shmid, NULL, 0);
if( (int)pProduct == -1 )
{
perror("shmat");
exit(EXIT_FAILURE);
}


//创建信号量
semid = semget(key1,SEM_NUMBER,IPC_CREAT|IPC_EXCL|0666);
if(semid < 0)
{//是否因为已存在而引起的失败
semid = semget(key1,0,0);
if(semid < 0)
{//创建失败
perror("semget");
exit(EXIT_FAILURE);
}
}else{//初始化信号集中的信号量
union semun{
int val;
struct semid_ds *buf;//buf指向信号量的描述结构体(设置信号量的属性)
unsigned short *array;//array用来为信号集中信号量设置初值
};


unsigned short initData[SEM_NUMBER];
initData[MAX_SEM] = MAX_PRODUCT;
initData[MIN_SEM] = 0;
initData[BIN_SEM] = 1;


union semun semInit;
semInit.array = initData;


if( semctl(semid, 0, SETALL, semData) < 0 )
{
perror("semctl");
exit(EXIT_FAILURE);
}


*pProduct = 0;
}


while(1)
{//生产消费过程
#ifdef PRODUCT
//p max_sem
assert(semop(semid,&lockMax,1) != -1); //20-1
//p bin_sem
assert(semop(semid,&lockBin,1) != -1); //1-1


//临界段
(*pProduct)++;
printf("[product] product number = %d\n", *pProduct);


//v bin_sem
assert(semop(semid,&unlockBin,1) != -1); //1-1+1
//v max_sem
assert(semop(semid,&unlockMin,1) != -1); //0+1

#endif


#ifdef CONSUME
//p min_sem
assert(semop(semid,&lockMin,1) != -1);
//p bin_sem
assert(semop(semid,&lockBin,1) != -1); //1-1
//临界段
(*pProduct)--;
printf("[consume] product number = %d\n", *pProduct);
//v bin_sem
assert(semop(semid,&unlockBin,1) != -1); //1-1+1
//v max_sem
assert(semop(semid,&unlockMax,1) != -1);
#endif


}


return 0;

}



程序没有删除创建的共享内存和信号量,所以运行后要用ipcs查看并用ipcrm sem semid和ipcrm shm shmid来删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值