⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 所打动叮叮咚咚 大 苏武到四的 main.c
💻 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",&currentSheng->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",&currentXiao->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 + -