C++ 在多线程函数中返回共享常量指针会导致计时问题吗

C++ 在多线程函数中返回共享常量指针会导致计时问题吗,c++,multithreading,shared-ptr,C++,Multithreading,Shared Ptr,例如: std::shared_ptr<config const> ClassA::getConfig() { folly::SharedMutex::ReadHolder rh(rwConfigLock_); return config_; } std::shared\u ptr ClassA::getConfig(){ folly::SharedMutex::ReadHolder rh(rwConfigLock); 返回配置; } 回程在锁里。但是,在释放锁之前是否复

例如:

std::shared_ptr<config const> ClassA::getConfig() {
  folly::SharedMutex::ReadHolder rh(rwConfigLock_);
  return config_;
}
std::shared\u ptr ClassA::getConfig(){
folly::SharedMutex::ReadHolder rh(rwConfigLock);
返回配置;
}

回程在锁里。但是,在释放锁之前是否复制了共享指针?我担心共享指针计数器会同时被不同的线程写入。

shared\u ptr
本身在设计上是线程安全的。因此对于返回
shared_ptr
实例而言,代码是安全的


更准确地说:需要复制
配置
才能保证线程安全。即使锁也不是可有可无的

假设您的锁在函数执行时阻止修改
config
,则
config
的复制将在锁定时完成。这一点非常重要,因为
shared\u ptr
不能提供强大的线程安全性。后者是安全读取可以异步修改的共享指针实例所必需的

幕后的问题是,在
shared\u ptr
读取
config\u
的指针之后,在它递增之前,引用计数器
config\u
可能刚刚被分配了一个新对象。在这种情况下,赋值运算符递减引用计数器,如果它返回到0(因为除了
config\uu
之外没有引用指向旧对象),它将丢弃旧对象。不幸的是,您的线程已经读取了旧的对象指针,并试图增加当前已销毁对象的计数器。这是UB


锁与副本一起防止出现这种情况,因为在释放锁时,
config\uu
后面的对象的引用计数器至少为2。一个用于副本,一个用于配置本身。因此,分配给
config\uuu

的任务无法销毁该对象是的,它是在释放锁之前复制的。但是你为什么需要一把锁呢<代码>共享_指针设计用于多线程上下文,因此我认为可以省略锁:。计数器操作始终是安全的。在这方面,请参见
std::shared_ptr
是线程安全的。这里不需要锁。没有意识到共享_ptr已经具备线程安全性!谢谢