[C++]_[初级]_[pthread多线程之生产者消费者模型]

场景:用于处理异步获取到的数据,便于数据按顺序同步执行处理。两者之间不直接依赖,降低耦合性;支持并发;支持忙闲不均。

以下是用读写文件来模拟生产者消费者模型,读取文件作为生产者,容器作为缓冲区,写文件作为消费者。

具体实例如下:

common_data.h

#ifndef _COMMON_DATA_H_  
#define _COMMON_DATA_H_  
#include <stdio.h>
#include <string>
#include <vector> 
#include <map>
#include <pthread.h>

enum
{
	kStatusStartWriteFile,
	kStatusCloseFile,
	kStatusWritingFile
	
};

extern unsigned int gFileOperatorType;
extern std::vector<std::string> gCommandQueue;
extern pthread_mutex_t gMonitorCommandQueueMutex;
extern pthread_cond_t gMonitorCommandQueueCond;
extern std::map<int,FILE*> IdToFileHandleMap;  
#endif  


data.h

#ifndef DATA_H_  
#define DATA_H_  
#include <stdio.h>  
#include <stdlib.h>  
#include <string> 
//向容器中加入一个(生产)。  
void AddProduct(std::string product_str);  
  
//从容器中取出全部产品信息(消费)。  
void ConsProduct();  

void DoCustomerData(std::string str);

  
#endif  


producer.h

/*************producer.h*************/  
      
#ifndef PRODUCER_H_  
#define PRODUCER_H_  
      
//生产者执行生产任务  
void *Producer(void *agg);  
      
#endif  


customer.h

    /************customer.h***********/  
      
#ifndef CUSTOMER_H_  
#define CUSTOMER_H_  
   
//消费者执行消费任务。  
void* Customer(void *agg);  
      
#endif  


common_data.cpp

#include "common_data.h"

unsigned int gFileOperatorType =kStatusStartWriteFile; 
std::vector<std::string> gCommandQueue;
std::map<int,FILE*> IdToFileHandleMap;
pthread_mutex_t gMonitorCommandQueueMutex = NULL;
pthread_cond_t gMonitorCommandQueueCond = NULL;


data.cpp

#include "data.h"  

#include "common_data.h"
#include<Windows.h>
  
int cond=1; 


//模拟下载文件,客户端接收到数据之后,执行命令,发送数据给另外一个手机,让其执行添加文件操作
void DoCustomerData(std::string str)
{
	//1.写文件
	FILE* wfile;
	if (IdToFileHandleMap.size() == 0)
        {
            wfile = _wfopen(L"D:\\new\\111.txt", L"wb");
            IdToFileHandleMap[1] = wfile;
           
        }else
        {
            wfile = IdToFileHandleMap[1];
        }
    
		//2写数据
		int len =str.length();
		printf("len:%d\n",len);
		fwrite(str.c_str(),len,1,wfile); 
		//3.关闭文件
		if(gFileOperatorType ==kStatusCloseFile)
		{
			wfile = IdToFileHandleMap[1];
			fclose(wfile);
			IdToFileHandleMap.clear();
		}
	 printf("*********** receiveMessage ***********%d\n",cond);
	 cond++;
}

  
void AddProduct(std::string product_str)
{  
    pthread_mutex_lock(&gMonitorCommandQueueMutex);
	gCommandQueue.push_back(product_str);
	printf("------生成产品---\n");
	pthread_cond_signal(&gMonitorCommandQueueCond);
	pthread_mutex_unlock(&gMonitorCommandQueueMutex);  
}  
  
  
void ConsProduct()
{  
  
	while(gCommandQueue.size()>0)
	{
		pthread_mutex_lock(&gMonitorCommandQueueMutex);
		printf("\n");
		//把消费的数据进行处理
		DoCustomerData(gCommandQueue.front());
		printf("\n");

		gCommandQueue.erase(gCommandQueue.begin());
		
		if(gCommandQueue.size()==0)
		{
			printf("继续等待....\n");
			printf("\n");
			pthread_cond_wait(&gMonitorCommandQueueCond,&gMonitorCommandQueueMutex);
		}
		 
		pthread_mutex_unlock(&gMonitorCommandQueueMutex);
	}
} 

 


producer.cpp

#include "producer.h"  
#include "data.h"  
#include <Windows.h>  
#include "common_data.h"

void *Producer(void *agg){  
    
    //文件读
	FILE *rfile =_wfopen(L"D:\\new\\11.txt",L"rb");
    fseek(rfile,0,SEEK_END);  
    unsigned int size =ftell(rfile);  
	int max_size =1024*4;
	char buff[1024*4];  
	fseek( rfile , 0 , SEEK_SET);
    unsigned int count =size/(max_size);  
    unsigned int temp_size =size%(max_size); 
	//读取文件数据 
	std::string str;
    for(unsigned int i = 0;i<count;++i)  
    { 
		memset(buff,0,max_size);
        fread(buff,max_size,1,rfile);  
        //存到一个std::string里 
		str.append((const char*)buff,max_size); 
		
        //写人数据到文件中  
		AddProduct(str);
		
		Sleep((int)(rand()/1000));
		str.clear();
    }  
    if(temp_size>0)  
    {  
		
		memset(buff,0,temp_size);
        fread(buff,temp_size,1,rfile);
		str.append((const char*)buff,temp_size); 
		
		gFileOperatorType =kStatusCloseFile;
		AddProduct(str); 

        str.clear();
		Sleep((int)(rand()/1000));
       
    } 
	//关闭文件 
    fclose(rfile);   
	
	return NULL;
}  


customer.cpp

#include "customer.h"  
#include "data.h"  
#include <Windows.h>
#include "common_data.h"
  
void* Customer(void *agg){ 
  
  while(1)
  {  
	ConsProduct();  
	Sleep((int)(rand()/3000)); 	
  }  
  return NULL;
}  


main.cpp

#include "customer.h"  
#include "producer.h"  
#include "data.h"  
#include <pthread.h>

#include "common_data.h" 
  
/******************************************************************* 
**实现生产者线程生产数据放入容器中,消费者线程负责消费数据***** 
*******************************************************************/  
  
int main(int argc,char* argv[])
{  
   pthread_t thread_pro;  
   pthread_t thread_cons;  
   printf("create....\n");     
  
	pthread_mutex_init(&gMonitorCommandQueueMutex,NULL);
	pthread_cond_init(&gMonitorCommandQueueCond,NULL);

   //创建生产者线程。  
   pthread_create(&thread_pro,NULL,Producer,NULL);  
   pthread_detach(thread_pro);

   //创建消费者线程。
   pthread_create(&thread_cons,NULL,Customer,NULL); 
   pthread_detach(thread_cons); 
   printf("finished!\n");  
   while(1){ 
	
   }  
   return 0;  
}  




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值