b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

linux多线程 借shared_ptr实现copy-on-write (1)(2)

电脑杂谈  发布时间:2018-02-05 17:05:02  来源:网络整理

?? ?? ?? ?? 2. write端在写之前,先检查引用计数是否为1,

?? ?? ?? ?? ?? 2.1 如果引用计数为1,则你是数据的唯一拥有者,直接修改。

?? ?? ?? ?? ?? 2.2 如果引用计数大于1,则你不是数据的唯一拥有者,还有其它拥有者,此时数据正在被其它拥有者read,则不能再原来的数据上并发写,应该创建一个副本,并在副本上修改,然后用副本替换以前的数据。这就需要用到一些shared_ptr的编程技法了:

void write()
{
    lock()
    if(!g_ptr.unique())
    {
        g_ptr.reset(new Foo(*g_ptr));
    }
    assert(g_ptr.unique());
    //write
    //
}
?? ?? ?? ?? ?? ?? ??解释一下代码:

?? ?? ?? ?? ?? ?? ?? ?? ??shared_ptr::unique(),当引用计数为1时返回true,否则false。

?? ?? ?? ?? ?? ?? ?? ?? 假设一个线程读,一个线程写,当写线程进入到if循环中时,原对象的引用计数为2,分别为tmpptr和g_ptr,此时reset()函数将原对象的引用计数减1,并且g_ptr已经指向了新的对象(用原对象构造),这样就完成了数据的拷贝,并且原对象还在,只是引用计数变成了1。

?? ?? ?? ?? ?? ?? ?? ?? 注意,reset()函数仅仅只是将原对象的引用计数减1,并没有将原对象析构,当原对象的引用计数为0时才会被析构。

linux多线程_linux不存程吗_linux下多线程处理多个

?? ?? 在《Linux多线程服务端编程—使用muduo C++网络库》的2.8节中,按照上面的方法,解决了2.1.1节的NonRecursiveMutex_test例子,在这就不累赘代码了。

??接着讲讲,《Linux多线程服务端编程—使用muduo C++网络库》的2.8节中的三种错误写法。

??错误一:直接修改g_foos所指的 FooList

void post(const Foo& f)
{
  MutexLockGuard lock(mutex);
  g_foos->push_back(f);
}
??如果有别的地方用到g_foos所指的 FooList的某一个迭代器,由于post()函数的push_bak()导致迭代器失效。

??错误二:试图缩小临界区,把copying移出临界区

void post(const Foo& f)
{
  FooListPtr newFoos(new FooList(*g_foos));
  newFoos->push_back(f);
  MutexLockGuard lock(mutex);
  g_foos = newFoos;
}
??临界区前的两行代码都是线程不安全的。

??程A中,g_foos指向的资源即将被析构(因此递减它所指向资源的引用计数),同时,程B中跑post()函数,正在执行"FooListPtr newFoos(new FooList(*g_foos));"这一行代码,此时正进行拷贝g_foos指向的资源,恐怕会出现core dump。因此要递增同一个引用计数。

void post(const Foo& f)
{
  FooListPtr oldFoos;
  {
    MutexLockGuard lock(mutex);
    oldFoos = g_foos;
  }
  FooListPtr newFoos(new FooList(*oldFoos));
  newFoos->push_back(f);
  MutexLockGuard lock(mutex);
  g_foos = newFoos;
}
??新建oldFoos指向原指针,防止被别的线程析构。但在这一行:FooListPtr newFoos(new FooList(*oldFoos)); ,如果有别的线程在修改g_foos所指的 FooList呢,后果可想而知。


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-65219-2.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...