利用boost的shared_ptr可以实现“读不阻塞写”。过程中每次读取不需要拷贝数据,而只需要在要写的时候拷贝一份数据:
点击(此处)折叠或打开
-
#include <iostream>
-
#include <cstdlib>
-
#include <map>
-
#include <vector>
-
#include <boost/smart_ptr.hpp>
-
#include <boost/make_shared.hpp>
-
#include <boost/enable_shared_from_this.hpp>
-
#include <boost/bind.hpp>
-
#include <boost/function.hpp>
-
#include <boost/noncopyable.hpp>
-
-
#include <pthread.h>
-
#include <unistd.h>
-
-
using namespace std;
-
-
-
class mutex_lock: public boost::noncopyable
-
{
-
public:
-
mutex_lock(){pthread_mutex_init(&_mutex, NULL);}
-
~mutex_lock(){pthread_mutex_destroy(&_mutex);}
-
void lock() {pthread_mutex_lock(&_mutex);}
-
void unlock() {pthread_mutex_unlock(&_mutex);}
-
private:
-
pthread_mutex_t _mutex;
-
};
-
-
class mutex_locker: public boost::noncopyable
-
{
-
public:
-
explicit mutex_locker(mutex_lock& lk): _lk(lk){_lk.lock();}
-
~mutex_locker(){_lk.unlock();}
-
private:
-
mutex_lock& _lk;
-
};
-
-
-
// 负责都和写的对象
-
class rwobj
-
{
-
public:
-
rwobj(){sp_data = boost::make_shared<vector<int> >();}
-
void read_data()
-
{
-
boost::shared_ptr<vector<int> > sp;
-
{
-
cout << "--------------------- read wait" << endl;
-
mutex_locker lk(l); // 临界区足够小,适合用mutex。
-
sp = sp_data; // 利用局部的shared_ptr来增加数据的引用计数,告诉写线程不要修改这份数据
-
cout << "read sleep 1" << endl;
-
sleep(1); // 为了阻塞其它线程
-
}
-
-
cout << "read size " << sp->size() << endl;
-
cout << "read sleep 2" << endl;
-
sleep(2);
-
}
-
-
void write_data(int i)
-
{
-
{
-
cout << "------------------------------ write wait" << endl;
-
mutex_locker lk(l); // 写线程的临界区比较大
-
if(!sp_data.unique())
-
{
-
// 如果sp_data引用计数大于1,说明有其他线程在读(通过read_data()提升了引用计数)。
-
// 此时将数据复制一份,再利用reset或者swap让sp_data指向新数据,老数据让读线程继续读。
-
// 这个写线程现在独占了sp_data,而之前那份数据在所有读线程读完之后,引用计数会变成0,被最后一个读线程自动析构。
-
sp_data.reset(new vector<int>(*sp_data));
-
cout << "-------------------------------- copy on write" << endl;
-
}
-
sp_data->push_back(i);
-
}
-
cout << "sleep write" << endl;
-
sleep(1);
-
}
-
private:
-
boost::shared_ptr<vector<int> > sp_data;
-
mutex_lock l;
-
};
-
-
-
rwobj obj;
-
-
// 读线程
-
void* read_thread(void* arg)
-
{
-
while(1)
-
{
-
obj.read_data();
-
}
-
}
-
-
写线程
-
void* write_thread(void* arg)
-
{
-
int i = 1;
-
while(1)
-
{
-
obj.write_data(i++);
-
}
-
}
-
-
int main()
-
{
-
pthread_t thread1,thread2, thread3;
-
pthread_create(&thread1, NULL, &read_thread, NULL );
-
pthread_create(&thread2, NULL, &read_thread, NULL );
-
pthread_create(&thread3, NULL, &write_thread, NULL );
-
pthread_join(thread1,NULL);
-
pthread_join(thread2,NULL);
-
pthread_join(thread3,NULL);
-
return 0;
-
}
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/26239116/viewspace-2125592/
,如需转载,请注明出处,否则将追究法律责任。