📄 main.c
字号:
#include "stdio.h"
#include <pthread.h>
#include <sys/time.h>
#include <malloc.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
/*缓冲区的最大数*/
#define Size 20
//记录生产者的人数
int sh=0;
//记录消费者的人数
int xiao1=0;
/*缓冲区的结构体*/
struct huan{
int isHave; //标记缓冲区是否有内容,有内容时,消费者才可以使用,
//没内容时,生产者才 可以往缓冲区内写东西
//0表示没有内容,1表示有内容
int jud; //标志缓冲区是否在被使用中,0代表未被使用,1表示使用中
int context; //缓冲的内容
};
//描述生产者,或者是消费者
struct person{
int end; //记录是否完成任务,0表示完成,1表示未完成任务
char * name; /*线程名*/
pthread_t thread; /*线程句柄*/
};
/*控制线程*/
//pthread_t thread;
//缓冲区
struct huan * huan[20];
//生产者,最多有10个生产者
struct person * sheng[10];
//消费者,最多有10个消费者
struct person * xiao[10];
//要放进入缓冲的内容的标记
int context=1;
int timesj(int i) //timesj函数,可产生一个随机数返回
{
int xt;
//为伪随机数初始化
xt = rand() %i+1;
return xt;
}
//生产者往缓冲区内放东西
//i是缓冲区的下标值,context是要放入缓冲区的内容,currentSheng是当前放进去的生产者
void put(int i,int context, struct person * currentSheng){
huan[i]->jud=1; //标志缓冲区正在使用
printf("\n生产者%s 往缓冲区%d 中写入%d",¤tSheng->name,i,context);
//输出当前生产者的名字,缓冲区的下标值和对应缓冲区里的内容
huan[i]->context=context; // 往缓冲区中放入内容
huan[i]->isHave=1; //表示有内容
huan[i]->jud=0; //释放空间,缓冲区未被使用
}
//消费者往缓冲区内拿东西
//i是缓冲区的下标值,currentXiao是当前拿缓冲区东西的消费者
int take(int i,struct person * currentXiao){
huan[i]->jud=1; //标志缓冲区正在使用
printf("\n消费者%s 往缓冲区%d 中拿出%d",¤tXiao->name,i,huan[i]->context);
//输出当前消费者的名字,缓冲区的下标值和对应缓冲区里的内容
huan[i]->isHave=0; //表示没有内容
huan[i]->jud=0; //释放空间,缓冲区未被使用
}
void * shengchan(struct person * currentSheng){
int i=0;
for(i=0;i<Size;i++){
//如果缓冲区没有内容而且缓冲区未被使用
if(huan[i]->isHave==0&&huan[i]->jud==0){
put(i,context++,currentSheng); //当前生产者往里面放内容
sleep(timesj(3)); //挂起一段时间
//线程沉睡若干秒,模仿线程因为工作而使用了的时间
}
}
currentSheng->end=1; //当前生产者任务未完成
}
void * xiaofei(struct person * currentXiao){
int i=0;
while(context<20)
for(i=0;i<Size;i++){
//如果缓冲区有内容而且缓冲区未被使用
if(huan[i]->isHave==1&&huan[i]->jud==0){
take(i,currentXiao); //当前消费者取出缓冲区的内容
sleep(timesj(3)); //挂起一段时间
//线程沉睡若干秒,模仿线程因为工作而使用了的时间
}
}
currentXiao->end=1; //当前消费者未完成任务
}
int getNumber(){
int a;
a=-99999;
while(1){
scanf("%d",&a);
getchar();
if(a<=-99999){
printf("\n你输入的不是数字,请重新输入:");
}
else break;
}
return a;
}
int main(){
int i=0,j=0;
time_t t;
//为随机函数做准备
srand((unsigned) time(&t)); // 以系统时间做种子,初始化rand()
for(i=0;i<Size;i++){
huan[i]=(struct huan *)malloc(sizeof(struct huan));
//动态分配存储区,返回一个指向struct huan的指针
huan[i]->isHave=0; //缓冲区没有内容
huan[i]->jud=0; //缓冲区未被使用
}
printf("请输入生产者的数量:");
/*
scanf("%d",&j);
getchar();
*/
j=getNumber();
sh=j;
for(i=0;i<j;i++){
sheng[i]=(struct person *)malloc(sizeof(struct person ));
//动态分配存储区,返回一个指向struct person的指针
printf("请输入生产者的名称:");
scanf("%s",&sheng[i]->name);
getchar();
sheng[i]->end=0; //标志生产者完成任务
}//for完成
printf("请输入消费者的数量:");
// scanf("%d",&j);
// getchar();
j=getNumber();
xiao1=j;
for(i=0;i<j;i++){
xiao[i]=(struct person *)malloc(sizeof(struct person));
//动态分配存储区,返回一个指向struct person的指针
printf("请输入消费者的名称:");
scanf("%s",&xiao[i]->name);
getchar();
xiao[i]->end=0; // 标志消费者完成任务
}
for(i=0;i<sh;i++){
//动态分配存储区,返回一个指向&sheng[i]->thread的指针
memset(&sheng[i]->thread, 0, sizeof(sheng[i]->thread));
//创建线程(LINUX) ,(调用(void *)shengchan方法,sheng[i]是方法的参数,&sheng[i]->thread为线 程地址)
if((pthread_create(&sheng[i]->thread, NULL, (void *)shengchan,sheng[i])) != 0) {
printf("线程创建失败!\n");
getchar();
exit(0);
return ;
}//if完成
}
for(i=0;i<xiao1;i++){
//动态分配存储区,返回一个指向&sheng[i]->thread的指针
//memset(&sheng[i]->thread, 0, sizeof(sheng[i]->thread));
//动态分配存储区,返回一个指向&xiao[i]->thread的指针
memset(&xiao[i]->thread, 0, sizeof(xiao[i]->thread));
//创建线程(LINUX) ,(调用(void *)xiaofei方法,xiao[i]是方法的参数,&xiao[i]->thread为线程地址)
if((pthread_create(&xiao[i]->thread, NULL, (void *)xiaofei,xiao[i])) != 0) {
printf("线程创建失败!\n");
getchar();
exit(0);
return ;
}
}
while(1){
sleep(18);
for(i=0;i<sh;i++) //如果生产者执行完,下一个继续生产
if(sheng[i]->end==0){
continue;
}
for(i=0;i<xiao1;i++) //如果消费者执行完,下一个继续消费
if(xiao[i]->end==0){
continue;
}
printf("\n演示完毕\n");
return;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -