在 lambda 中锁定 std::shared_ptr 的复制操作
Posted
技术标签:
【中文标题】在 lambda 中锁定 std::shared_ptr 的复制操作【英文标题】:Locking copy operation of std::shared_ptr inside lambda 【发布时间】:2020-01-21 17:49:20 【问题描述】:对于这个示例代码:
#include <iostream>
#include <thread>
#include <mutex>
#include <memory>
struct A
int _i;
A(int i):_i(i)
std::cout<<"A() "<<_i<<std::endl;
~A()
std::cout<<"~A() "<<_i<<std::endl;
void Print()
std::cout<<"Print() "<<_i<<std::endl;
;
struct B
std::shared_ptr<A> Asp;
std::mutex AspMutex;
void SetA()
static int i = 0;
std::unique_lock<std::mutex> lock(AspMutex);
Asp = std::make_shared<A>(i);
void AccessA1()
std::shared_ptr<A> aspCopy;
std::unique_lock<std::mutex> lock(AspMutex);
aspCopy = Asp;
(*aspCopy).Print();
void AccessA2()
auto aspCopy = [&]()
std::unique_lock<std::mutex> lock(AspMutex);
return Asp;
();
(*aspCopy).Print();
void AccessA3()
(*[&]()
std::unique_lock<std::mutex> lock(AspMutex);
return Asp;
()
).Print();
;
int main()
B b;
b.SetA();
std::thread t([&]b.SetA(););
b.AccessA1();
b.AccessA2();
b.AccessA3();
t.join();
我很好奇 c++17(或更高版本)标准是否会保证 A::Access1
和 A::Access2
方法是线程安全的(std::shared_ptr
的副本将受 lock
保护)。
【问题讨论】:
你能解释一下目前线程不安全的地方吗?因为您似乎在锁后访问Asp
。
我不明白这个问题。你锁定,然后复制。为什么那不是线程安全的?
编辑:没关系,我在std::thread
之前错过了b.SetA()
。
@NicolBolas 据我所知没有。我只是好奇它是否会以任何方式危险。例如。 Access2
中的 Lambda 不能复制 shared_ptr
而是使用原始的等。
【参考方案1】:
是的。锁使A::Access1
和A::Access2
线程安全,并发SetA
。在 C++17 中仍然如此。
【讨论】:
以上是关于在 lambda 中锁定 std::shared_ptr 的复制操作的主要内容,如果未能解决你的问题,请参考以下文章
SAL 注释:std::shared_ptr 的 _Ret_maybenull_
std::shared_mutex 是不是偏爱作者而不是读者?
在 c++11 中转换 std::future 或 std::shared_future
为啥我不能在 C++0x 中对 std::shared_ptr 的向量执行 std::copy?
在 msvs 2013 中 std::shared_ptr 的 compare_exchange_weak 是不是损坏?