C++11怎么实现无锁队列

发布时间:2021-08-12 09:25:59 作者:chen
来源:亿速云 阅读:281

这篇文章主要讲解了“C++11怎么实现无锁队列”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++11怎么实现无锁队列”吧!

无锁操作的本质依赖的原子操作,C++11提供了atomic的原子操作支持

atomic

compare_exchange_weak / compare_exchange_strong
当前值与期望值相等时,修改当前值为设定值,返回true
当前值与期望值不等时,将期望值修改为当前值,返回false

memory_order枚举值

C++11怎么实现无锁队列

template<typename T>
class lock_free_stack
{
private:
    struct node
    {
        T data;
        node* next;
        node(T const& data_):
        data(data_)
        {
        }
    };

    std::atomic<node*> head;

public:
    void push(T const& data)
    {
        node* const new_node=new node(data);
        new_node->next=head.load();  

        /*
        ** 当前值.compare_exchange_weak(期望值, 设置值)
        ** 单线程的情况:
        ** 第一次执行while循环:
        ** 此时当前值与期望值相等,修改当前值为设定值 head = new_node,返回true
        ** 多线程的情况:
        ** 第一次执行循环体的时候:
        ** compare_exchange_weak如果失败, 返回false, 证明有其他线程更新了栈顶head,
        ** 当前值与期望值不等时,将期望值修改为当前值, 即new_node->next等于新的栈顶head,
        ** 被其他线程更新的新栈顶值会被更新到new_node->next中,
        ** 因此循环可以直接再次尝试压栈而无需由程序员更新new_node->next。
        ** 然后第二次执行循环体:
        ** 此时 head == new_node->next, 所以 head = new_node.
        ** 如果这是仍有其他线程干扰,则仍为循环更新new_node->next
        */
        while(!head.compare_exchange_weak(new_node->next,new_node));
    }
};

CAS原子操作

示例代码如下:

bool compare_and_swap ( int *memory_location, int expected_value, int new_value)
{
    if (*memory_location == expected_value)
    {
        *memory_location = new_value;
        return true;
    }
    return false;
}

ABA问题

所谓ABA(见维基百科的ABA词条),问题基本是这个样子:

虽然P1以为变量值没有改变,继续执行了,但是这个会引发一些潜在的问题。ABA问题最容易发生在lock free 的算法中的,CAS首当其冲,因为CAS判断的是指针的地址。如果这个地址被重用了呢,问题就很大了。(地址被重用是很经常发生的,一个内存分配后释放了,再分配,很有可能还是原来的地址)

eg:
好比你拿着一个装满钱的手提箱在飞机场,此时过来了一个火辣性感的美女,然后她很暖昧地挑逗着你,并趁你不注意的时候,把用一个一模一样的手提箱和你那装满钱的箱子调了个包,然后就离开了,你看到你的手提箱还在那,于是就提着手提箱去赶飞机去了。

这就是ABA的问题。

Fetch-And-Add (FAA)

一般用来对变量做+1的原子操作

Test-And-Set (TAS)

写值到某个内存位置并传回其旧值

感谢各位的阅读,以上就是“C++11怎么实现无锁队列”的内容了,经过本文的学习后,相信大家对C++11怎么实现无锁队列这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

推荐阅读:
  1. C++11多线程
  2. C++11如何实现简易定时器

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

c++11

上一篇:js怎么实现弹幕功能

下一篇:如何使用vmware测试PXE批量安装服务器

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》