gpt4 book ai didi

c++ - shared_ptr 和 const 方法线程安全

转载 作者:行者123 更新时间:2023-11-28 05:40:45 25 4
gpt4 key购买 nike

假设我们有一个带有 const 方法(仅)的 class A

class A
{
public:
void method1() const;
void method2() const;
}

此外,我们还有另一个 class B,它具有 class Ashared_ptr 以及返回它并使用互斥保护更改它的方法:

class B
{
std::shared_ptr<A> ptr;
std::mutex m;
public:
B()
{
ptr = std::make_shared<A>();
}

std::shared_ptr<A> getPtr() const
{
mutex_on_stack mut(m);
return ptr;
}

void resetPtr()
{
mutex_on_stack mut(m);
ptr.reset(new A());
}
}

ptr 变量受互斥锁保护,因此我假设它是线程安全的。但是我不确定内部对象本身的安全性。

B objB;

//thread 1
auto p1 = objB->getPtr();
p1->method1(); //calling const method

//thread 2
auto p2 = objB->getPtr();
p2->method2(); //calling const method

//thread 3
objB->resetPtr();

线程 1 和 2 调用 getPtr() 方法并在复制时增加 shared_ptr 的引用计数器。所以我认为内部指针不会被线程 3 中的 resetPtr() 意外删除。此外,方法 method1method2 是 const 所以它不修改内部对象。但我可能是错的。

所以我有两个问题:

  1. 上面的代码是线程安全的吗?
  2. A 类 是线程安全的吗?

最佳答案

A 是线程安全的,因为它只使用 const 函数,可以假设这些函数不会改变外部可见状态。如果类也有 mutable 成员,则 const 函数能够修改内部状态,通常假设任何 mutable 成员是同步的,因此一个对象的两个并发读者永远不会遇到竞争条件。


shared_ptr 内容的访问是线程安全的,事实上什至不需要额外的互斥锁同步。来自 cppreference :

All member functions (including copy constructor and copy assignment) can be called by multiple threads on different instances of shared_ptr without additional synchronization even if these instances are copies and share ownership of the same object.

但是,这仅在您不调用相关 shared_ptr 的非 const 函数时才成立:

If multiple threads of execution access the same shared_ptr without synchronization and any of those accesses uses a non-const member function of shared_ptr then a data race will occur; the shared_ptr overloads of atomic functions can be used to prevent the data race.

所以 B 类在没有互斥量的情况下现在不会是线程安全的,因为您正在调用函数上的 reset。如果您使用 atomic overloads for shared_ptr 而不是调用 reset ,它将在没有互斥锁的情况下成为线程安全的.

实际上,要确保线程安全,您唯一需要做的就是确保您的 RAII 包装器持续到它正在执行的函数作用域结束。

关于 RAII 包装器的主题,您不需要推出自己的锁定-解锁机制。标准库已经以 lock_guard 的形式为您提供了 RAII 锁。 , unique_lockshared_lock .像这样的简单场景可能最适合 lock_guard,它被设计成一个简单的作用域锁。

关于c++ - shared_ptr 和 const 方法线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37144799/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com