如果我在多线程中重置相同的 shared_ptr 则不会崩溃
no crash if I reset the same shared_ptr in multi-threads
我只是想确认在多线程中重置为同一个带锁的智能指针是否安全?如果没有lock_guard,因为它不是线程安全的方法,所以不安全?我想重置不是线程安全的,但是,如果我删除了锁,则不会观察到崩溃。
class foo {
public:
foo()
{
std::cout << "foo constructed" << std::endl;
}
~foo()
{
std::cout << "foo destructed" << std::endl;
}
};
int main(int argc, const char * argv[]) {
std::shared_ptr<foo> f = std::make_shared<foo>();
conqueue = dispatch_queue_create("MyConcurrentDiapatchQueue", DISPATCH_QUEUE_CONCURRENT);
static std::mutex io_mutex;
for (int i = 0; i < 100000; i++)
{
dispatch_async(conqueue, ^{
std::lock_guard<std::mutex> lk(io_mutex); // no crash without this line as well
f.reset(); // it's safe? No crash if I reset the same shared_ptr in multi-threads.
});
}
return 0;
}
shared_ptr
对象不是 thread-safe,pointed-to 对象也不是。只有引用计数是thread-safe。所以是的,你需要使用守卫。
在C++20中,有std::atomic<std::shared_ptr<T>>
.
文档不保证该组件的安全性。本质上,如果标准对此只字未提,那么您的假设是正确的。您必须拥有锁门或任何提供相同功能的东西。
崩溃可能无法观察到,因为在您尝试在并发线程中读取指针之前您没有竞争条件,因为您实际上并没有尝试使用该值(重置所做的只是更改指针值)。
好吧,你不能指望你不能观察到 UB,UB 是薛定谔的猫。
我只是想确认在多线程中重置为同一个带锁的智能指针是否安全?如果没有lock_guard,因为它不是线程安全的方法,所以不安全?我想重置不是线程安全的,但是,如果我删除了锁,则不会观察到崩溃。
class foo {
public:
foo()
{
std::cout << "foo constructed" << std::endl;
}
~foo()
{
std::cout << "foo destructed" << std::endl;
}
};
int main(int argc, const char * argv[]) {
std::shared_ptr<foo> f = std::make_shared<foo>();
conqueue = dispatch_queue_create("MyConcurrentDiapatchQueue", DISPATCH_QUEUE_CONCURRENT);
static std::mutex io_mutex;
for (int i = 0; i < 100000; i++)
{
dispatch_async(conqueue, ^{
std::lock_guard<std::mutex> lk(io_mutex); // no crash without this line as well
f.reset(); // it's safe? No crash if I reset the same shared_ptr in multi-threads.
});
}
return 0;
}
shared_ptr
对象不是 thread-safe,pointed-to 对象也不是。只有引用计数是thread-safe。所以是的,你需要使用守卫。
在C++20中,有std::atomic<std::shared_ptr<T>>
.
文档不保证该组件的安全性。本质上,如果标准对此只字未提,那么您的假设是正确的。您必须拥有锁门或任何提供相同功能的东西。
崩溃可能无法观察到,因为在您尝试在并发线程中读取指针之前您没有竞争条件,因为您实际上并没有尝试使用该值(重置所做的只是更改指针值)。
好吧,你不能指望你不能观察到 UB,UB 是薛定谔的猫。