对付多线程用户来说,无锁行列步队的入队和出队操作是线程安全的,不用再加锁掌握。

什么是无锁行列步队

行列步队每个开拓者都知道,那么什么又是无锁行列步队呢?字面理解起来便是一个无锁状态的行列步队,多个线程(消费者)同时操作数据的时候不须要加锁,由于加/解锁都是一个很花费资源的动作。

php队列需不要加锁熟悉无锁队列 SQL

数据构造

我们先看一下无锁行列步队的底层实现数据构造。

无锁行列步队底层的数据构造实现办法紧张有两种:数组 和 链接。

数组

在首次初始化时,须要申请一块连接的大的内存。
读写数据直接从数据的指定位置操作即可,韶光繁芜度为O(1)。

缺陷:数组长度有限,一旦数组索引位置写满,则无法连续写入,即行列步队有上限。

链表

不用像数组一样,刚开始就申请一块连接的大的内存空间。
只有在每次写时数据的时候,申请这个数据节点大小的内存即可,这样就可以实现无限的写入,没有长度限定问题。

缺陷:每次写数据都要申请内存,在写的场景,最差的情形是多少个数据就申请多少次内存,而每次申请都是一个花费资源的动作。

可以看到无锁底层的实现的不同各有上风。
多数据情形下,我们都采取链表来实现无锁行列步队,紧张缘故原由便是写入可以没有长度的限定。
比较每次申请都要费时来说,知足前面的条件是我们最基本的哀求。
当然紧张还是真正的利用场景。

CAS

CAS 是 Compare And Swap 的简称, 属于 乐不雅观锁,这是一个并发同步原语. 伪代码如下:

bool compare_and_swap(int reg, int oldval, int newval){ int reg_val = reg; if(reg_val == oldval) { reg = newval; return true; } return false;}

CAS操作有三个参数,分别表示 内存值V、旧的预期值A 和 修正后的更新值B。

判断变量内存某个位置的值是否为预期值,如果是则变动为新的值,并返回true,这个过程是原子性操作。
如果修正失落败,可能须要重试再次实行CAS操作,直到修正成功,一样平常称此过程为自旋。
可以看到每次调用 CAS 命令前须要先读取旧值 oldval。

现在险些所有的CPU指令都支持CAS的原子操作,X86下对应的是 CMPXCHG 汇编指令。
有了这个操作,我们就可以用其来实现各种无锁的数据构造。

利用场景

无锁行列步队也属于行列步队的一种,以是大部分行列步队的利用场景都可以利用它来代替其它有锁行列步队,无锁行列步队通过不加锁的办法提高行列步队性能。

认识无锁行列步队 | 《Linux就该这么学》 (linuxprobe.com)