无锁队列
CAS原子操作 – 一个针对每个变量的锁
bool CAS(*addr, oldVal, newVal);
lock(); exec(); unlock();
CAS操作和上面的主要的不同点就是CAS只能针对一个变量进行一个原子操作;本质上就是CAS取代了lock的锁操作,然后修改数据结构使临界区更小。CAS本身依旧是个锁。修改了数据结构之后将临界区粒度缩小到一个变量上,然后以CAS的形式进行保护,最终就是所谓的无锁队列。
适用场景
适用在每秒处理十几万元素的时候进行考虑,每秒几百、几千个元素性能提升不大;
无锁队列实现
- 链表的dummy(虚拟)节点,仅仅作为一个节点使用,并不具备存储的功能;可以方便链表的管理,没太大用,和具体实现细节有关;
CAS和无锁队列是怎么产生联系的?CAS本质上不也是个锁吗
本质上无锁队列就是基于CAS的锁粒度更新的、锁内置在队列结构中的一个队列;
锁的保护粒度
锁的保护粒度越小,效率执行越快;
boost库中的无锁队列
boost::lockfree实现了三种无锁数据结构,分别如下:
#include "boost/lockfree/queue.hpp"
boost::lockfree::queue
一个无锁的 多生产者 / 多消费者 队列。
boost::lockfree::stack
一个无锁的 多生产者 / 多消费者 栈。
boost::lockfree::spsc_queue
一个无锁的 单生产者 / 单消费者 队列,通常被称为环形缓冲区
example中的无锁队列 – 单写单读的无锁队列
插入元素
- 首先将待插入元素设置到back中
- 调用push进行添加
优势
整个的优势就在于减少malloc的次数:
- 一个是malloc chunk的概念:一次性申请N个元素空间
- 一个是缓冲的概念,就是缓冲一个chunk块先不释放资源,然后需要申请的时候直接用上去;多个的话就释放掉前面的几个chunk块;
- 锁的粒度小,等待不需要冗余等待
CAS的应用
锁
example中的无锁队列 – 多写多读的无锁队列
涉及到的代码为ArrayLockFreeQueue.h 和 ArrayLockFreeQueueImp.h
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/226626.html原文链接:https://javaforall.net
