繁体   English   中英

boost::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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM