C++ boost::atomic_shared_ptr绝对安全吗?

C++ boost::atomic_shared_ptr绝对安全吗?,c++,boost,shared-ptr,C++,Boost,Shared Ptr,众所周知,std::shared_ptr不是线程安全的。 因此,很容易通过简单的程序在web上找到大量崩溃的代码示例来说明std::shared_ptr的缺点。 但是我找不到boost::atomic_shared_ptr的任何版本 这是否意味着我可以使用boost::atomic_shared_ptr而不用担心它会在多线程环境中使我的应用程序崩溃? (当然,boost::atomic_shared_ptr可能包含bug。因此我想知道,它“设计”是否安全。)您可以将shared_指针与atomi

众所周知,std::shared_ptr不是线程安全的。 因此,很容易通过简单的程序在web上找到大量崩溃的代码示例来说明std::shared_ptr的缺点。 但是我找不到boost::atomic_shared_ptr的任何版本 这是否意味着我可以使用boost::atomic_shared_ptr而不用担心它会在多线程环境中使我的应用程序崩溃?
(当然,boost::atomic_shared_ptr可能包含bug。因此我想知道,它“设计”是否安全。)

您可以将shared_指针与
atomic_load
/
atomic_store
一起使用,尽管它在C++11中已被取代:

我自己找不到很多例子,尽管我在这里用过:,在这里

不管这些,这些都不能保证代码的安全,因为您仍将共享共享指针指向的对象,这使得代码与以前一样容易出错

您仍然需要向代码中添加适当的同步。

std::atomicstd::shared\u ptr是线程安全的,但仅用于读取和写入指针本身的值。它的使用并不能保证共享的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. 
    }
}
//为了简单起见,使用foo指向的单个数据编写器。
//契约:仅从主线程设置值(例如)
//设置值,然后在所有参数发生更改时调用apply_
//你说得对。
结构Foo
{
无效集_值a(int x);
//...  
无效集_值z(int x);
void apply_changes();
};   
//使用全球数据进行silplicity,tis可能是某个类别的成员,
//或者在应用程序中的任何稳定内存位置。
//多个线程可能会重新分配或重置此对象,因此std::atomic。
std::原子全局ptr;
使某些函数无效()
{
//设置或重置全局\u ptr属性
如果(!全局_ptr)
返回;
全局\u ptr->set\u valueA(42);//可能出现错误的\u alloc异常
//发生在这里
//如果设置或重置了全局_ptr,会发生什么情况
//通过这两个语句之间的另一个线程?
全局\u ptr->set\u valueB(17);//此处可能发生错误的\u alloc异常。
全局_ptr->apply_changes();//根据Foo合同未定义的行为
//可能发生在这里。
}
//由于这个原因,正确的用法应该是。。。
使某些函数无效()
{
//设置或重置全局\u ptr属性
//由于全局_ptr是原子的,因此可以保证这条线路不会崩溃
//并且总是返回一个格式良好的共享\u ptr。如果是事实,那就是
//std::atomic提供的唯一保证。
if(标准::共享\u ptr本地\u副本=全局\u ptr)
{
//请注意,本地拷贝保证指向同一对象,直到
//范围结束。
本地复制->设置值A(42);
本地复制->设置值B(17);
本地复制->应用更改();
//如果全局_ptr已更改,则在
//退出范围。
}
}

因此,imho,在使用原子共享指针时,仍然必须采取一些基本的预防措施,无论是对指向的数据执行读操作还是写操作。

您是说标准化为?阅读文档时您发现了什么?是的,
原子碎片ptr
为读取和修改指针本身提供了强大的线程安全性。相关信息这是否意味着boost::atomic_shared_ptr及其c++20模拟(按设计)中的内存管理层是绝对安全的?事实上,我正在寻找一个内存管理系统,用于允许速度慢但必须安全的代码片段。我特别说过:“所有这些都不会使代码安全”——并解释了原因。没有银弹。[虽然在PUR函数语言中编程可以获得一定的长度,这适合某些领域和算法,但是C++有一定的流行性。根据您所说的“内存管理层”的确切含义,您可以认为正确使用时“绝对安全”。但在我看来,这并不是一个能增加很多价值的声明。