shared_ptr实现多线程读写copy-on-write

原创 数据库开发技术 作者:liiinuuux 时间:2016-09-26 13:14:25  473  0

利用 shared_ptr可以实现“读不阻塞写”。过程中每次读取不需要拷贝数据,而只需要在要写的时候拷贝一份数据:

点击(此处)折叠或打开

#include 

#include 

#include 

#include 

#include

#include 

#include 

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 >();}

void read_data()

{

boost::shared_ptr > 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(*sp_data)); 

cout << "-------------------------------- copy on write" << endl;

}

sp_data->push_back(i);

}

cout << "sleep write" << endl;

sleep(1);

}

private:

boost::shared_ptr > 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;

}

你可能感兴趣的:(shared_ptr实现多线程读写copy-on-write)