场景:用于处理异步获取到的数据,便于数据按顺序同步执行处理。两者之间不直接依赖,降低耦合性;支持并发;支持忙闲不均。
以下是用读写文件来模拟生产者消费者模型,读取文件作为生产者,容器作为缓冲区,写文件作为消费者。
具体实例如下:
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;
}