生产者消费者模型是操作系统中一种重要的进程/线程同步与互斥模型,在实际的项目中应用十分的广泛。
1、我们编写一个高并发的web服务器,需要使用到线程池技术,其中的线程池用来处理不同客户的请求任务,不同客户的请求任务我们把它们放入一个请求队列中,如果请求队列中有任务,那线程就从请求队列中取任务,如果请求队列中没任务,那线程就阻塞,那么这些线程就是系统中的消费者。同理,系统中也会有相应的生产者进程把客户的请求任务放入请求队列中。
2、在高并发的web服务器中我们经常使用数据库连接池技术来加快系统的响应速度,其中的连接池也是对应着生产者、消费者模型中的数据缓冲区。
3、订单处理:用户提交订单,订单进入引擎的阻塞队列中,由专门的线程从阻塞队列中获取数据并处理。
4、读者写者问题等等。
下面我们采用信号量+互斥锁的方式来实现一个简单的生产者消费者模型,代码如下:
#include <pthread.h>
#include <exception>
#include <semaphore.h>
#include <vector>
#include <iostream>
#include <cstdio>
using namespace std;
class sem
{
public:
sem()
{
if(sem_init(&m_sem,0,0)!=0)
{
throw std::exception();
}
}
~sem()
{
sem_destroy(&m_sem);
}
bool wait()
{
return sem_wait(&m_sem)==0;
}
bool post()
{
return sem_post(&m_sem)==0;
}
private:
sem_t m_sem;
};
class locker
{
public:
locker()
{
if(pthread_mutex_init(&m_lock,NULL)!=0)
{
throw std::exception();
}
}
~locker()
{
pthread_mutex_destroy(&m_lock);
}
bool lock()
{
return pthread_mutex_lock(&m_lock)==0;
}
bool unlock()
{
return pthread_mutex_unlock(&m_lock)==0;
}
private:
pthread_mutex_t m_lock;
};
//生产者,消费者
class model
{
public:
void product()
{
m_thread=new pthread_t();
if(pthread_create(m_thread,NULL,worker,this)!=0)
{
delete m_thread;
throw std::exception();
}
while(true)
{
queuesize->post();
lo->lock();
queue.push_back(0);
cout<<"input a number"<<endl;
lo->unlock();
}
}
void comsuer() //子线程执行消费者
{
while(true)
{
queuesize->wait();
lo->lock();
queue.pop_back();
cout<<"get a number"<<endl;
lo->unlock();
}
}
static void* worker(void*arg)
{
model*m=(model*)arg;
m->comsuer();
return m;
}
model()
{
queuesize=new sem();
lo=new locker();
}
~model()
{
delete m_thread;
m_thread=NULL;
delete queuesize;
queuesize=NULL;
}
private:
pthread_t* m_thread;
sem* queuesize;
locker* lo;
vector<int> queue; //缓冲区
};
int main(void)
{
model*m=new model();
m->product();
return 0;
}