#include <iostream>
#include <boost/thread.hpp>
#include <boost/interprocess/sync/interprocess_semaphore.hpp>
using namespace boost::interprocess;
const int size = 5;
struct Data_buff
{
Data_buff()
:putSemaphore(2), getSemaphore(0), getMutex(1)
{
put = buf1;
nput = buf2;
get = 0;
}
int buf1[size];
int buf2[size];
int *put;
int *nput;
int *get;
interprocess_semaphore putSemaphore, // 是否可以进行数据的添加
getSemaphore, // 是否可以进行数据的读取
getMutex; // 是否可以进行指针的更改
};
struct MutexBuf
{
boost::mutex dataMutex; // 数据访问的互斥变量
boost::condition_variable_any putCond; // 是否可以进行数据添加,如果没有缓冲区则不能,添加完一个缓冲区的数据,但是read没有释放get
boost::condition_variable_any getCond; // 是否可以进行数据读取,如果get为0,则不能
int buf1[size];
int buf2[size];
int *put;
int *nput;
int *get;
MutexBuf()
{
put = buf1;
nput = buf2;
get = 0;
}
};
const int total = 4*size;
int putcount = 0;
int getcount = 0;
Data_buff buf;
MutexBuf mutexBuf;
void MutexPut()
{
while(true)
{
if (putcount >= total)
return;
for( int i = 0; i < size; ++i )
mutexBuf.put[i] = putcount + i;
putcount += size;
{
boost::mutex::scoped_lock lock(mutexBuf.dataMutex);
// 如果表征不能在缓冲区中添加数据:添加完一个缓冲区中的数据,但是get没有释放掉,则不能添加
while(mutexBuf.get)
mutexBuf.putCond.wait(mutexBuf.dataMutex);
mutexBuf.get = mutexBuf.put;
mutexBuf.put = mutexBuf.nput;
// 通知读者,可以进行数据的操作
mutexBuf.getCond.notify_one();
}
}
}
void MutexRead()
{
while(true)
{
if(getcount >= total)
return;
{
boost::mutex::scoped_lock lock(mutexBuf.dataMutex);
// 判断是否可以进行数据读
while(!mutexBuf.get)
mutexBuf.getCond.wait(mutexBuf.dataMutex);
}
std::cout << "addr = " << mutexBuf.get << "\n";
for( int i = 0; i < size; ++i )
std::cout << "value = " << mutexBuf.get[i] << ",";
std::cout << "\n";
getcount += size;
{
boost::mutex::scoped_lock lock(mutexBuf.dataMutex);
// 释放get的读操作区域
mutexBuf.nput = mutexBuf.get;
mutexBuf.get = 0;
mutexBuf.putCond.notify_one();
}
}
}
void put()
{
while(true)
{
if (putcount >= total)
return;
buf.putSemaphore.wait();
for( int i = 0; i < size; ++i )
buf.put[i] = putcount + i;
putcount += size;
// 判断get是否被read用了,如果用了才可以在重新设置
buf.getMutex.wait();
buf.get = buf.put;
buf.put = buf.nput;
// get可用,通知get
buf.getSemaphore.post();
}
}
void read()
{
while(true)
{
if (getcount >= total)
return;
buf.getSemaphore.wait();
std::cout << "addr = " << buf.get << "\n";
for( int i = 0; i < size; ++i )
std::cout << "value = " << buf.get[i] << ",";
std::cout << "\n";
getcount += size;
buf.nput = buf.get;
buf.getMutex.post(); // get被read用完,那么可以进行改写
buf.putSemaphore.post(); // 可以进行数据的put
}
}
int main(int argc, char *argv[])
{
boost::thread_group gr;
gr.create_thread(MutexPut);
boost::this_thread::sleep(boost::posix_time::seconds(5));
for( int i = 0 ; i < size; ++i )
{
std::cout << "buf1["<< i << "] = " << mutexBuf.buf1[i] << ",";
}
std::cout << "\n";
for( int i = 0 ; i < size; ++i )
{
std::cout<< "buf2["<< i << "] = " << mutexBuf.buf2[i] << ",";
}
std::cout << "\n";
boost::this_thread::sleep(boost::posix_time::seconds(5));
gr.create_thread(MutexRead);
gr.join_all();
return 0;
};