shared_ptr实现copy-on-write

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/linux_Allen/article/details/79886110

最近再看陈硕的《Linux多线程服务端编程使用muduoC++网络库》,2.8节看到这个内容:使用shared_ptr实现copy-on-write的手法降低锁竞争。

目的: 利用普通mutex替换读写锁

  • shared_ptr是引用技术型智能指针,当只有一个观察者时,引用计数为1。
  • 对于write端,如果发现引用计数为1(即当前只有自己持有智能指针),那可以加锁后安全的修改。如果大于1,则需要拷贝当前数据构再修改。代码实现就是拷贝构造一个新的FooList,然后在这个新的Foolist中写。
  • 对于read端,在读之前加锁后将引用计数加1,就可以安全的读取。将引用计数加1,保证了写端不会去并发写。
void read()
{
    FoolPtr foos; //智能指针对象
    {
    MutexLockGuard lock(mutex_);
    foos = g_foos; //引用计数加1
    }
    for( .... )
    //read ...
}

void write(const foo& f)
{
    MutexLockGuard lock(mutex_);
    if(!g_foos.unique()) //如果此时引用计数不为1,则需要拷贝对象
    {
        g_foos.reset(new FooList(*g_foos));
    }
    g_foos->push(f); 
}

g_foos.reset 当g_foos仅仅只是将引用计数减1,只有当引用计数为1的时候,才会析构其管理的对象。

性能分析:

  • read时:构造一个智能指针对象,引用计数加1,但是大大减小了锁的粒度
  • write时:当发现引用计数大于1时,即有别的线程正在读,此时需要拷贝构造一个新的容器对象出来,然后在新的对象里write。当别的线程读取完毕时,随着智能指针对象析构,引用计数为0,原有容器对象也就析构了

猜你喜欢

转载自blog.csdn.net/linux_Allen/article/details/79886110