简单的生产者消费者模式,缓冲区采用stack,当然你也可以使用list circle-buffer等数据结构;
读写数据时要加锁,实现线程的同步,这里采用条件变量来处理读写动作,先锁定互斥变量,然后调用wait循环检查stack条件(写入时检查是否已满,读取时检查是否为空),直到满足条件,然后通知其它线程。
代码如下:
#include<stack>
#include<mutex>
#include<thread>
using namespace std;
class CBuffer
{
public:
explicit CBuffer(int iCapacity = 0);
~CBuffer();
public:
void PutData();
void GetData();
void put(int x);
void get(int* x);
bool bEmpty();
bool bFull();
private:
mutex m_mtx;
condition_variable m_condition_put;
condition_variable m_condition_get;
int m_iUnRead;
int m_iCapacity;
stack<int> m_stack;
}
//.cpp
#include"ConditionVariable.h"
CBuffer::CBuffer(int iCapacity)
:m_iCapacity(iCapacity)
{
}
CBuffer::~CBuffer()
{
}
void CBuffer::PutData()
{
for(int i = 0; i < 10;i++)
{
cout<<"put:"<<i<<endl;
put(i);
}
}
void CBuffer::GetData()
{
int iData;
for(int i = 0; i < 10;i++)
{
get(&iData);
cout<<"get:"<<iData<<endl;
}
}
void CBuffer::put(int x)
{
unique_lock<mutex> lock(m_mtx);
for(;bFull();)
{
cout<<"buffer is full:"<<endl;
//需要等待线程,直到条件满足,然后写数据
m_condition_put.wait(lock);
}
m_stack.push(x);
++m_iUnRead;
lock.unlock();
//通知读数据的线程,可以读取数据了
m_condition_get.notify_one();
}
void CBuffer::get(int* x)
{
unique_lock<mutex> lock(m_mtx);
for(;bEmpty();)
{
cout<<"buffer is empty:"<<endl;
//需要等待线程,直到条件满足,然后读数据
m_condition_get.wait(lock);
}
*x = m_stack.top();
m_stack.pop();
m_iUnRead--;
//通知写数据的线程,可以写数据了
m_condition_put.notify_one();
}
bool CBuffer::bFull()
{
return m_iUnRead == m_iCapacity;
}
bool CBuffer::bEmpty()
{
return m_iUnRead == 0;
}
void main()
{
CBuffer buffer(5);
thread thread_put(&CBuffer::PutData,&buffer); //可参考c++11中thread构造函数的用法
thread thread_get1(&CBuffer::GetData,&buffer);
thread thread_get2(&CBuffer::GetData,&buffer);
thread_put.join(); //join用于阻塞线程,直到线程结束
thread_get1.join();
thread_get2.join();
}