[英]What is the difference between std::shared_ptr and std::experimental::atomic_shared_ptr?
[英]Is boost::atomic_shared_ptr absolutely safe?
众所周知 std::shared_ptr 不是线程安全的。 所以很容易在web中找到很多崩溃的代码示例,用简单的程序来说明std::shared_ptr的缺点。 但是我找不到任何 boost::atomic_shared_ptr 这是否意味着我可以使用 boost::atomic_shared_ptr 而不必担心它会使我的应用程序在多线程环境中崩溃? (当然 boost::atomic_shared_ptr 可以包含错误。所以我想知道 - “设计”是否安全。)
从 C++11 开始,您可以将 shared_pointer 与atomic_load
/ atomic_store
一起使用,即使它在 c++20 中被取代:
https://en.cppreference.com/w/cpp/memory/shared_ptr/atomic
我自己找不到很多示例,尽管我在这里使用了它: How to use boost::atomic_store with shared_ptr<T> and shared_ptr<const T>? ,这里是 https://github.com/sehe/msghub/blob/std-over-boost/src/msghub.cpp#L25
不管这一切,这些都不会使您的代码安全,因为您仍将共享共享指针指向的对象,这使您的代码像以前一样容易发生数据竞争。
您仍然需要为您的代码添加适当的同步。
std::atomicstd::shared_ptr<> 是线程安全的,但仅用于读取和写入指针本身的值。 它的使用并没有使 shared_ptr 的所有使用成为线程安全的。
考虑一下:
// using a single writer of data pointed to by foo for simplicity.
// contract: only set values from main thread (for example)
// set values, then call apply_changes when all your parameters
// are correct.
struct Foo
{
void set_valueA(int x);
//...
void set_valueZ(int x);
void apply_changes();
};
// using global data for silplicity, tis could be a member of some class,
// or in any stable memory location in an application.
// More than one thread may reallocate or reset this object, hence the std::atomic.
std::atomic<std::shared_ptr<Foo>> global_ptr;
void some_function()
{
// Set or reset global_ptr attributes
if (!global_ptr)
return;
global_ptr->set_valueA(42); // a bad_alloc exception could
// happen here
// what happens if global_ptr is set or reset
// by another thread in between these two statements?
global_ptr->set_valueB(17); // a bad_alloc exception may occur here.
global_ptr->apply_changes(); // undefined behavior as per contract of Foo
// may happen here.
}
// for this reason, proper usage would be...
void some_function()
{
// Set or reset global_ptr attributes
// since global_ptr is atomic, it is guaranteed that this line will not crash
// and will always return a well-formed shared_ptr. If fact, that's the
// one and only guarantee given by std::atomic<std::shared_ptr<>>.
if (std::shared_ptr<Foo> local_copy = global_ptr)
{
// Note that local_copy is guaranteed to point to the same object until
// end of scope.
local_copy->set_valueA(42);
local_copy->set_valueB(17);
local_copy->apply_changes();
// if global_ptr has changed, then memory will be released when
// exiting scope.
}
}
因此,恕我直言,在使用原子共享指针时仍然必须采取一些基本的预防措施,无论是对指向数据的读取还是写入操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.