C++20的原子智能指针

本文介绍了C++20中引入的原子智能指针特性,如何解决多线程环境下智能指针的数据安全问题。通过示例展示了如何在并发栈中使用原子智能指针进行线程安全的操作,如push_front、pop_front和find。C++20的这一改进减少了对锁的依赖,提高了并发性能,并使得代码更加简洁。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、原子变量和智能指针

在前面学习时提到过智能指针本身不是线程安全的,因为虽然其计数器是线程安全控制但数据不是,这也就是说其在多线程中赋值时,会产生冲突。而原子变量恰恰能够解决这个问题,不过在早先的c++标准中,原子变量不支持智能指针,所以要实现多线程间数据的安全控制,要么使用锁,要么使用全局的非成员原子操作(std::atomic_load(), atomic_store()等)。
但是,c++20中,原子操作增加了对智能指针类型的支持,这样就可以安全快速的控制智能指针在不同线程间的数据操作了。

二、原子智能指针

在c++的文档中可以看到:

template<class U>
struct atomic<std::shared_ptr<U>>; (C++20 起)
template<class U>
struct atomic<std::weak_ptr<U>>;   (C++20 起)

目前来看相关的代码实现仍然是使用了CAS的方式,更具体的得需要看实现库的具体的源码。

三、应用例程

看一个例程:

template<typename T> 
class concurrent_stack { 
    struct Node { 
        T t; 
        shared_ptr<Node> next; 
    }; 
    atomic_shared_ptr<Node> head; 
    // C++11中使用非"atomic_" 就必须使用前面提到的孤立函数std::tomic_load 等
public: 
    class reference { 
        shared_ptr<Node> p; 
        <snip> 
    }; 
    auto find(T t) const { 
        auto p = head.load(); // C++11使用atomic_load(&head) 
        while (p && p->t != t) 
            p = p->next; 
        return reference(move(p)); 
    } 
    auto front() const { 
        return reference(head); 
    } 
    void push_front(T t) { 
        auto p = make_shared<Node>(); 
        p->t = t; p->next = head; 
        while (!head.compare_exchange_weak(p->next, p)){ 
    } // C++11使用 atomic_compare_exchange_weak(&head, &p->next, p); }     
    void pop_front() { 
        auto p = head.load(); 
        while (p && !head.compare_exchange_weak(p, p->next)) {
        } // C++11使用atomic_compare_exchange_weak(&head, &p, p->next); 
    } 
};

这个例程是Herb Sutter 的 N4162 论文中的一段,c++的文档中目前还没有看到。

四、总结

按照c++文件档中所说,std::shared_ptr的控制块是安全,但如果使用其访问非const的成员函数则会出现数据竞争,也就是数据冲突。这样说来,这个原子智能指针的用处还是不小,毕竟一般操作智能指针还是以操作函数居多。其实这也是c++减少孤立函数,扩大现有功能的范围的一种进步。不断内聚,去除耦合。这样也符合一般人们的习惯。
换句话说,多一些普遍适用,少一些特例应用。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值