//先把那个数据池实现了再说。
//more UserData.h
#ifndef USER_DATA_H
#define USER_DATA_H
#include <pthread.h>
#include <queue>
#include <string>
using namespace std;
class UserData //定义一个数据缓冲池,这样就可以限定这个缓冲池的大小,轻松实现生产者消费者模型,使之更加安全可靠。
{
public:
UserData();
~UserData();
void SetMaxNum(int m);
void DataPush(string str);
string DataPop();
private:
queue<string> strQueue;
int maxNum;
pthread_mutex_t lock;
pthread_cond_t full;
pthread_cond_t empty;
};
#endif
//more UserData.cpp
#include "UserData.h"
#include <iostream>
UserData::UserData()
{
pthread_mutex_init(&lock,0);
pthread_cond_init(&full,0);
pthread_cond_init(&empty,0);
}
UserData::~UserData()
{
pthread_mutex_destroy(&lock);
pthread_cond_destroy(&full);
pthread_cond_destroy(&empty);
}
void UserData::SetMaxNum(int m)
{
maxNum = m;
}
void UserData::DataPush(string str)
{
pthread_mutex_lock(&lock);
while(strQueue.size() >= maxNum)
{
std::cout << "full" << endl;
pthread_cond_wait(&full,&lock);
}
strQueue.push(str);
pthread_cond_broadcast(&empty);
pthread_mutex_unlock(&lock);
}
string UserData::DataPop()
{
string resStr;
pthread_mutex_lock(&lock);
while(strQueue.empty())
{
std::cout << "empty" << endl;
pthread_cond_wait(&empty,&lock);
}
resStr = strQueue.front();
strQueue.pop();
pthread_cond_broadcast(&full);
pthread_mutex_unlock(&lock);
return resStr;
}
//main.cpp
#include <iostream>
using namespace std;
#include <pthread.h>
#include "UserData.h"
#include <unistd.h>
class Thread //编写一个线程基类,是如此的简单,呵呵
{
private:
pthread_t t;
public:
virtual void run()=0;
static void* run(void* p);
void start();
};
void* Thread::run(void* p)
{
Thread* pThread = (Thread*)p;
pThread->run();
}
void Thread::start()
{
pthread_create(&t,0,run,this);
}
//线程基类到此编写完毕,下面的类只要继承这个基类就可以轻松实现线程的创建了。
class Productor:public Thread //这个生产者就这样随便写一个了,他的任务就是给缓冲池里面扔数据。
{
private:
UserData* pUserData;
public:
void run();
Productor(UserData* ud);
void Produce();
};
Productor::Productor(UserData* ud)
{
pUserData = ud;
}
{
Produce();
delete this; //非常抱歉,这里又来这一套,但是以后我会再想一个办法解决内存释放的问题的。
}
void Productor::Produce()
{
int num = 15; //在这里又来搞这一套,连续往数据池里扔15个数据。当然这里不一定是真正的连续,因为数据池的最大数据量可能不到15,
//数据满了之后//那个扔数据的过程就会等待,等到数据池不满为止。
string str = "love";while(num--)
{
pUserData->DataPush(str);
cout << "product " << str << endl;
}
}
class Consumer:public Thread //简单定义一个消费者
{
private:
UserData* pUserData;
public:
void run();
Consumer(UserData* ud);
void Consume();
};
Consumer::Consumer(UserData* ud)
{
pUserData = ud;
}
void Consumer::run()
{
int num = 15;
while(num--)
{
Consume();
sleep(1); //这是让消费者消费的慢一点,好让大家知道,生产者很快,但是数据池满了之后,他会等待消费者消费,等不满之后再生产,他会很耐心,不会等不及
//就往下跑。
}
delete this;
}
void Consumer::Consume()
{
cout << "consume " << pUserData->DataPop() << endl;}
int main()
{
UserData* pUserData = new UserData();
pUserData->SetMaxNum(8);
Productor* pPro = new Productor(pUserData);
pPro->start();
Consumer* pCon = new Consumer(pUserData);
pCon->start();
delete pUserData;// 注意new和delete是应该成对出现的。虽然上面中间两个new在这里你没有看到delete,但是其实是有的,我在run函数里写了。
pause();return 0;
}