/*
** 模拟生产者/消费者模型
** 模拟过程:
** 生产者 消费者
**
** 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;
** 模拟生产者/消费者模型
** 模拟过程:
** 生产者 消费者
**
** 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来删除。