【发布时间】: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而是使用原始的等。
标签: c++ multithreading thread-safety c++17