简体   繁体   English

std::weak_ptr 和相应的 std::shared_ptr 之间是否存在数据竞争?

[英]Is there any data race between std::weak_ptr and corresponding std::shared_ptr?

According to cppref, accessing const members of shared_ptr across multiple threads is safe.根据 cppref,跨多个线程访问shared_ptrconst成员是安全的。 But is this statement valid when we have a weak_ptr that corresponds to a shared_ptr ?但是,当我们有一个对应于shared_ptrweak_ptr时,这个语句是否有效?

As an example assume the following code:例如,假设以下代码:

#include <memory>
#include <iostream>
#include <thread>

std::shared_ptr<int> sp;
std::weak_ptr<int> gw;

int main()
{
    sp = std::make_shared<int>(42);
    gw = sp;
    auto th1 = std::thread([]{
        for (int i = 0; i < 200; i++) {
            if (sp.use_count() > 1) {
                std::cout << i << "\n";
                std::this_thread::yield();
            }
        }
    });
    auto th2 = std::thread([]{
        for (int i = 0; i < 20; i++) {
            if (auto l = gw.lock()) {
                std::cout << "locked ->" << l.use_count() << "\n";
                std::this_thread::yield();
            }
        }
    });
    th1.join();
    th2.join();
}

This code creates 2 threads.此代码创建 2 个线程。 One checks use_count() of shared_ptr() which is a const method and the other one use lock() to lock weak_ptr() which also is a const method too.一个检查shared_ptr()use_count() ,这是一个const方法,另一个使用lock()锁定weak_ptr()这也是一个const方法。 But in reality, when I call lock on weak_ptr , I practically increase reference count of shared_ptr which is not thread safe unless reference count is internally guarded.但实际上,当我在weak_ptr上调用lock时,我实际上增加了shared_ptr的引用计数,这不是线程安全的,除非引用计数受到内部保护。 I wonder if I will have a data race in situations like this.我想知道在这种情况下我是否会进行数据竞赛。 Is this supposed to be thread-safe by standard?按照标准,这应该是线程安全的吗?

Yes.是的。 The reference counter is atomic, so there are no data races in your example.引用计数器是原子的,因此您的示例中没有数据竞争。

That being said, mutable operations on objects pointed by std::shared_ptr are not atomic, so they must be guarded as you would guard access via a plain pointer.话虽这么说,对std::shared_ptr指向的对象的可变操作不是原子的,因此必须像通过普通指针保护访问一样保护它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM