V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kkkbbb
V2EX  ›  程序员

c++多线程 shared_ptr 生命期问题

  •  1
     
  •   kkkbbb · 325 天前 · 803 次点击
    这是一个创建于 325 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在书上看到这个例子: 2023-06-06_191542.png

    划线处使用 swap 方式,而不是 data_=newData,解释是:使旧数据的析构发生在临界区外,缩小临界区的范围,但是我理解通过这种方式,newData 虽然指向了旧数据的引用,但是出了 if 判断作用域引用不也为 0 ,也会产生析构啊,不知道是哪理解错了?

    8 条回复    2023-06-08 08:46:25 +08:00
    codehz
        1
    codehz  
       325 天前
    所以这个函数在 C++20 就直接移除了
    kkkbbb
        2
    kkkbbb  
    OP
       325 天前
    @codehz 所以这种方式旧数据的析构也是发生在临界区里吧
    codehz
        3
    codehz  
       325 天前
    被移除的是 unique(),因为多线程环境下不能确保不会出现 toctou 的问题(
    ----
    整个判定 unique 的方法就不对,如果到处都有 lock 保护,那判不判断 unique 都一样
    唯一想到的用例就是懒拷贝,此时 mutex 可能不是同一个,那还是有 toctou 的问题,可能在判定 unique 的时候它还是 unique 的,但是到了更新的时候就不 unique 了
    kkkbbb
        4
    kkkbbb  
    OP
       325 天前
    @codehz 就算真的不是 unique ,“使旧数据的析构发生在临界区外,缩小临界区的范围”这句话的意思是什么?
    codehz
        5
    codehz  
       325 天前
    @kkkbbb 你是说在 if !unique 里面不用 data_=newData ?那说明文章在脱裤子放屁
    operator=的实现基本上等价于
    shared_ptr<T>(r).swap(*this);
    return *this;
    它这里手动复制 Map ,除非 MapPtr 里有做什么 non trivial 的事情,否则基本上可以认为没有区别
    kkkbbb
        6
    kkkbbb  
    OP
       325 天前
    @codehz 还是有区别的吧,operator= newData 的指向的对象不会发生变化,swap 会交换指向的内容
    codehz
        7
    codehz  
       325 天前
    @kkkbbb 但也就复制一份右侧的而已,而右侧的无论如何也不会在这个位置和别人共享访问,所以没有区别(除了多复制一次)
    要避免额外复制的话,用 std::move()让它移动过去就可以了)
    kkkbbb
        8
    kkkbbb  
    OP
       323 天前 via Android
    乌龙了,图片上的代码和书上还有点区别,书上的 lock 临界区是在 if 作用域里,所以解释的没问题。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1599 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 17:18 · PVG 01:18 · LAX 10:18 · JFK 13:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.