无锁队列的实现-循环数组
2018-07-13 08:48:57来源:编程学习网 阅读 ()
通过CAS操作免锁设计:
- CAS原子 操作(Compare & Set):包含三个操作数,内存值V、旧的预期值 oldval、要修改的新值newval,当且仅当内存V中的值和旧值oldval相同时,将内存V修改为newval。
- 数组队列是一个循环数组,队列少用一个元素,当头等于尾标示队空,尾加1等于头标示队满。
- 数组的元素用EMPTY(无数据,标示可以入队)和FULL(有数据,标示可以出队)标记指示,数组一开始全部初始化成 EMPTY标示空队列。
- EnQue 操作:如果当前队尾位置为EMPTY,标示线程可以在当前位置入队,通过CAS原子操作把该位置设置为FULL,避免其它线程操作这个位置,操作完后修改队尾位置。各个线程竞争新的队尾位置。如下图所示:
- 线程T1/T2竞争队尾位置。
- T1竞争成功,首先设置FULL标记,然后对该位置进行操作。
- T2轮询该位置标识为FULL继续轮询。
- T1操作完成后将队尾位置后移。
- T1/T2又开始竞争新的队尾。
- DeQue 操作:如果当前队头位置为FULL,标示线程可以在当前位置出队,通过CAS原子操作把该位置设置为EMPTY,避免其它线程操作这个位置,操作完后修改队头位置。各个线程竞争新的队头位置。
- 操作没有加锁,每个线程都假设没有冲突的去完成操作,如果因为冲突失败就重试。
通过CAS、FAA、FAS操作免锁设计:
- FAA操作:原子加1操作,返回更新前的值。
- FAS操作:原子减1操作,返回更新前的值。
- 增加writeableCnt指示队列还可以写入元素个数,readableCnt指示队列中存在的元素个数。用来控制可以并发操作的线程个数。
- EnQue 操作:通过原子加操作给每个要求操作的线程分配为唯一一个位置信息存放在局部变量pos中,各个线程并行的操作对应位置的信息,不再需要轮询等待。如下图所示:
- T1/T2线程初始操作队尾的两个位置。
- T1操作完后直接操作下一个队尾位置。
- DeQue 操作:如果当前队头位置为FULL,标示线程可以在当前位置出队,通过CAS原子操作把该位置设置为EMPTY,避免其它线程操作这个位置,操作完后修改队头位置。各个线程竞争新的队头位置。
- 多个线程可以同时进行入队,避免了在同一个位置等待轮询,对效率有明显提升。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- PHP简单实现单点登录功能示例 2019-10-09
- thinkphp5框架前后端分离项目实现分页功能的方法分析 2019-10-08
- PHP7 安装event扩展的实现方法 2019-10-08
- php实现的数组转xml案例分析 2019-09-30
- PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql 2019-09-23
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash