利用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博客 ” ,链接:http://blog.itpub.net/26239116/viewspace-2125592/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/26239116/viewspace-2125592/