经典同步互斥 ---- 生产者消费者问题
程序员文章站
2022-07-05 09:02:35
...
生产者消费者问题:多个生产者,多个消费者进行同步互斥。把生产信息和消费信息写入.csv文件记录。
//pc.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include<sys/sem.h>
#define N 32 //32个货架
#define Prod 7 //生产者7个
#define Cons 5 //消费者5个
#define M_KEY 5201
#define E_KEY 5207
#define F_KEY 5208
int in = 0; //生产者放产品的位置
int out = 0; //消费者取产品的位置
int tm = 0;//到达时间
int buf[N] = {0}; //N个货架,开始时初始化为0,没有产品
int mutex,empty,full; //声明信号量
int id = 0; //生产者消费者id
int P(int sid) //P操作
{
struct sembuf sb={0,-1,0};
return semop(sid, &sb, 1);
}
int V(int sid) //V操作
{
struct sembuf sb={0,1,0};
return semop(sid, &sb, 1);
};
void produce()
{
FILE *f0;
char buf[40] = {0};
if(NULL == (f0=fopen("/home/ssm/shiyan2wenjian/pctest.csv","a"))) //打开一个pctest.csv文件
{
printf("can not open file\n");
}
else
{
//printf("put information succed!\n"); //创建成功就输出这句话
sprintf(buf,"\n生产者%d,%d,丽雅,毛巾,1\n",id,tm);
//printf("%s", buf);
fwrite(buf,sizeof(buf),1,f0);//将获取到的字符串写入目标文件
fclose(f0); //关闭文件
}
}
void consume()
{
FILE *f0;
char buf[40] = {0};
if(NULL == (f0=fopen("/home/ssm/shiyan2wenjian/pctest.csv","a"))) //打开一个pc.csv文件
{
printf("can not open file\n");
}
else
{
//printf("put information succed!\n"); //创建成功就输出这句话
sprintf(buf,"\n消费者%d,%d,丽雅,毛巾,1\n",id,tm);
//printf("%s", buf);
fwrite(buf,sizeof(buf),1,f0);//将获取到的字符串写入目标文件
fclose(f0); //关闭文件
}
}
void* Producer(void *p) //生产者
{
P(empty); //查空货架
P(mutex); //申请访问货架区
id++;
tm++;
produce(); //生产
buf[in]=1; //放产品
in=(in+1)%N;
printf("放置时间%d, 生产者%d, 货架号%d, 金星, 毛巾\n",id,tm,in-1);
V(mutex); //释放货架区
V(full); //发满货架消息
}
void* Consumer(void *p) //消费者
{
P(full); //查满货架
P(mutex); //申请访问货架区
id++;
tm++;
buf[out]=0; //取产品
out=(out+1)%N;
printf("取货时间%d, 消费者%d, 货架号%d, 金星, 毛巾\n",id,tm,out-1);
consume(); //消费
V(mutex); //释放货架区
V(empty); //发空货架消息
}
int main(int argc,char *argv[])
{
pthread_t id1[Prod]; //生产者
pthread_t id2[Cons]; //消费者
char keyboard;
int i;
int ret[Prod];
mutex=semget(M_KEY,1,IPC_CREAT|0660);//创建信号量
semctl(mutex,0,SETVAL,1); //初值1
empty=semget(E_KEY,1,IPC_CREAT|0660);//创建空信号量
semctl(empty,0,SETVAL,N); //初值N
full=semget(F_KEY,1,IPC_CREAT|0660);//创建满信号量
semctl(full,0,SETVAL,0); //初值0
// 创建Prod个生产者线程
for(i = 0; i < Prod; i++)
{
ret[i] = pthread_create(&id1[i], NULL, Producer, (void *)(&i));
if(ret[i] != 0)
{
printf("product%d creation failed \n", i);
exit(1);
}
}
//创建Cons个消费者线程
for(i = 0; i < Cons; i++)
{
ret[i] = pthread_create(&id2[i], NULL, Consumer, NULL);
if(ret[i] != 0)
{
printf("prochase%d creation failed \n", i);
exit(1);
}
}
keyboard=getchar();
for(i=0;i<Prod; i++)
pthread_cancel(id1[i]); //终止生产者线程
for(i=0;i<Cons; i++)
pthread_cancel(id2[i]); //终止消费者线程
semctl(mutex, 0, IPC_RMID); //删除信号量
semctl(empty, 0, IPC_RMID); //删除信号量
semctl(full, 0, IPC_RMID); //删除信号量
return 0;
}
运行结果如下:
写入的文件数据如下:
上一篇: 经典的生产者消费者问题
下一篇: linux 防火墙 终端修改