[英]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.