一种无锁并发消息处理机制的实现方法

文档序号:6619731阅读:474来源:国知局
一种无锁并发消息处理机制的实现方法
【专利摘要】本发明公开了一种无锁并发消息处理机制的实现方法,采用环型数组作为数据缓冲区,有利于缓存预读,同时避免了链表结构所带来的每次节点操作都需要申请或释放内存的弊端,提高了效率;对于多生产者单消费者模型的并发控制问题,采用CAS和内存屏障保证互斥,不使用加锁的方式,避免锁的低效带来的性能劣化;对于无锁技术中常见的ABA问题,采用双保险的CAS技术,避免ABA问题的发生;对于伪共享问题,在头指针、尾指针和容量三个变量间使用缓冲行填充方法,避免头指针、尾指针和容量三个变量在同一个缓冲行中,造成伪共享问题;同时将数组长度设为2的指数倍,采用“与操作”的位运算来获取数组下标,提高了整体效率。
【专利说明】一种无锁并发消息处理机制的实现方法
[0001]

【技术领域】
[0002]本发明属于计算机软件工程【技术领域】,涉及一种无锁并发消息处理机制的实现方法。
[0003]

【背景技术】
[0004]在一个消息驱动的系统中,消息处理机制是系统的重点和难点问题,消息处理机制的优劣影响到整个系统的稳定性和效率。
[0005]现有的消息处理机制一般都是基于队列(采用链表实现)和锁算法为核心来实现的。消息队列采用链表结构来保存。对于多线程对共享数据的操作采用信号量和锁来解决同步和互斥问题。
[0006]现有的机制有几点对性能有较大影响: (I)链表节点分散,不在同一片存储区域,不利于缓存预读。
[0007](2)链表节点每次操作时需要申请或释放内存,比较低效。
[0008](3)习惯的编程方式导致头指针、尾指针和容量三个变量常常在一个缓存行中,造成伪共享问题。
[0009](4)大量的锁操作造成效率低下。
[0010]


【发明内容】

[0011]本发明是基于现有需求,改变传统的消息处理机制,采用基于环形数组缓冲区的无锁并发机制来进行消息处理,提出了一种在确保系统稳定性的前提下、尽量优化性能的无锁并发消息处理机制的实现方法。
[0012]本发明所采用的技术方案是:一种无锁并发消息处理机制的实现方法,其特征在于:储存消息数据的缓冲区采用环形数组结构,而不是采用链表结构,使数据存储在同一片存储区域,便于缓存预读,同时避免链表节点每次操作时所需要申请或释放内存操作,提高效率。
[0013]缓冲区的中心数据结构是一个基于定长数组的环形队列。在数组创建时可以预先分配好空间,插入新元素时只要将新元素数据拷贝到已经分配好的内存中即可,在删除旧元素时也不需要释放内存空间。使用环形数组的缓冲区避免了频繁的内存操作,同时对数组的元素访问对CPU缓存是非常友好的。
[0014]作为优选,对于多生产者单消费者模型的并发控制问题,采用CAS和内存屏障保证互斥,不使用加锁的方式,避免锁的低效带来的性能劣化。
[0015]采用CAS和内存屏障代替互斥锁来保证资源共享时的互斥。锁是用来做并发最简单的方式,当然其代价也是最高的。内核态的锁上锁的时候需要操作系统进行一次上下文切换,等待锁的线程会被挂起直至锁释放。在上下文切换的时候,CPU之前缓存的指令和数据都将失效,对性能有很大的损失。用户态的锁虽然避免了这些问题,但是往往是通过自旋锁来实现(自旋即忙等待),而自旋在竞争激烈的时候开销非常大(因为忙等待一直在消耗CPU资源)。不使用锁,使用CAS严格意义上说仍然是使用锁,因为CAS本质上也是一种乐观锁,只不过是CPU级别指令,不涉及到操作系统,所以效率很高。使用CAS时不像上锁那样需要一次上下文切换,只需要处理器锁住它的指令流水线来保证原子性。但CAS并不是无开销的,它会涉及到对指令pipeline加锁,并且会用到内存屏障(用来刷新内存状态,简单理解就是把缓存中,寄存器中的数据同步到内存中去)。现代CPU是乱序执行的,也就是程序顺序与实际的执行顺序很可能是不一致的。在单线程执行时这不是个问题,但是在多线程环境下这种乱序就可能会对执行结果产生很大的影响了。内存屏障提供了一种控制程序执行顺序的手段。
[0016]作为优选,为避免ABA问题,采用双保险的CAS技术,将计算机能一次操作的存储区域分为高地址部分和低地址部分,高地址部分为标志位,低地址部分为数据位,同时对标志位和数据位进行CAS操作,避免ABA问题发生。
[0017]在入队列时采用双保险的CAS是为了避免ABA问题。所谓ABA问题简单理解就是:
(1)进程Pl在共享变量中读到值为A;
(2)Pl被抢占了,进程P2执行;
(3)P2把共享变量里的值从A改成了 B,再改回到A,此时被Pl抢占;
(4)Pl回来看到共享变量里的值没有被改变,于是继续执行。
[0018]虽然Pl以为变量值没有改变,继续执行了,但是这个会引发一些潜在的问题。ABA问题最容易发生在无锁的算法中。
[0019]作为优选,对于伪共享问题,在头指针、尾指针和容量三个变量间使用缓冲行填充方法,避免头指针、尾指针和容量三个变量在同一个缓冲行中,造成伪共享问题。
[0020]在头指针、尾指针和容量三个变量间使用缓冲行填充方法可以避免伪共享问题。缓存行是指CPU在做缓存的时候有个最小缓存单元,在同一个单元内的数据被同时被加载到缓存中,充分利用缓存行可以大大降低数据读写的延迟,错误利用缓存行也会导致缓存不同替换,反复失效。缓存系统中是以缓存行为单位存储的。当多线程修改互相独立的变量时,如果这些变量共享同一个缓存行,就会无意中影响彼此的性能,这就是伪共享。缓存行上的写竞争是运行在对称式多处理器系统中并行线程实现可伸缩性最重要的限制因素。
[0021]作为优选,所述的环形数组长度设为2的指数倍,采用“与操作”的位运算代替“取余操作”来获取数组下标,利用计算机“与操作”的效率高于“取余操作”的特性来提高整体效率。
[0022]关于环形数组的大小选择有一个讲究,一般对环形队列中取下标通常会用到取余操作,在大部分处理器上,取余操作并不高效。因此可以将数组大小设定为2的指数倍,这样计算余数只需要通过位操作“index & ( size -1 ) ”就能够得到实际的数组下标。
[0023]本发明是一种在确保系统稳定性的前提下、尽量优化性能的无锁并发消息处理机制的实现方法。
[0024]

【专利附图】

【附图说明】
[0025]图1:为本发明实施例中写入数据流程图;
图2:为本发明实施例中读取数据流程图;
图3:为本发明实施例中ABA问题示意图;
图4:为本发明实施例中为解决ABA问题设计的存储数据结构示意图;
图5:为本发明实施例中ABA问题解决流程示意图。
[0026]

【具体实施方式】
[0027]为了便于本领域普通技术人员理解和实施本发明,下面结合附图及实施例对本发明作进一步的详细描述,应当理解,此处所描述的实施示例仅用于说明和解释本发明,并不用于限定本发明。
[0028]本发明所采用的技术方案是:一种无锁并发消息处理机制的实现方法,储存消息数据的缓冲区采用环形数组结构,而不是采用链表结构,使数据存储在同一片存储区域,便于缓存预读,同时避免链表节点每次操作时所需要申请或释放内存操作,提高效率;环形数组长度设为2的指数倍,采用“与操作”的位运算代替“取余操作”来获取数组下标,利用计算机“与操作”的效率高于“取余操作”的特性来提高整体效率;对于多生产者单消费者模型的并发控制问题,采用CAS和内存屏障保证互斥,不使用加锁的方式,避免锁的低效带来的性能劣化;为避免ABA问题,采用双保险的CAS技术,将计算机能一次操作的存储区域分为高地址部分和低地址部分,高地址部分为标志位,低地址部分为数据位,同时对标志位和数据位进行CAS操作,避免ABA问题发生;对于伪共享问题,在头指针、尾指针和容量三个变量间使用缓冲行填充方法,避免头指针、尾指针和容量三个变量在同一个缓冲行中,造成伪共享问题。
[0029]本实施例的环形缓冲区的中心数据结构采用一个基于定长数组(长度为2的指数倍,模型中选择2048)的环形队列。环形缓冲区里头尾指针都是不断永远向前计数,不断在环形缓冲区中循环。
[0030]#define MAX_QUEUE_LEN 2048
struct msg_queue_cb {
u32buffer[MAX_QUEUE_LEN];
struct padded—datawritepos;
struct padded—datareadpos;
struct padded—dataqueue_len;
sem—tfull_sem;
sem—tempty—sem;
};
本实施例伪共享解决办法是在头指针、尾指针、容量三个数据变量间使用缓冲行填充方式。CPU会把数据从内存加载到高速缓存中,这样可以获得更好的性能,高速缓存默认大小是64字节为一个区域,CPU机制限制只能一个CPU的一个线程访问(写)这个高速缓存区。CPU在将主内存中数据加载到高速缓存时,如果发现被加载的数据不足64字节,那么就会加载多个数据,以填满自己的64字节,这样一个高速缓存中可能加载了两个对象指针,一个CPU —个高速缓存,双核就是两个CPU各自一个高速缓存,那么两个高速缓存中各有两个对象指针,都是指向相同的两个对象。因为一个CPU只能访问(写)自己高速缓存区中数据,相当于给这个数据加锁,那么另外一个CPU同时访问自己高速缓存中同样数据时将会被锁定不能访问。这就发生与锁机制类似的性能陷进,所以,尽管两个线程是在写两个不同的字段值,也会因为双核CPU底层机制发生伪装的共享,并没有真正共享,其实还是排他性的独享。解决办法是填满高速缓存的64字节,这样CPU将数据加载到高速缓存时,就只能加载一个了。根据高速缓存大小的不同可以修改填充内容的大小。

【权利要求】
1.一种无锁并发消息处理机制的实现方法,其特征在于:储存消息数据的缓冲区采用环形数组结构,而不是采用链表结构,使数据存储在同一片存储区域,便于缓存预读,同时避免链表节点每次操作时所需要申请或释放内存操作,提高效率。
2.根据权利要求1所述的无锁并发消息处理机制的实现方法,其特征在于:对于多生产者单消费者模型的并发控制问题,采用CAS和内存屏障保证互斥,不使用加锁的方式,避免锁的低效带来的性能劣化。
3.根据权利要求1所述的无锁并发消息处理机制的实现方法,其特征在于:为避免ABA问题,采用双保险的CAS技术,将计算机能一次操作的存储区域分为高地址部分和低地址部分,高地址部分为标志位,低地址部分为数据位,同时对标志位和数据位进行CAS操作,避免ABA问题发生。
4.根据权利要求1所述的无锁并发消息处理机制的实现方法,其特征在于:对于伪共享问题,在头指针、尾指针和容量三个变量间使用缓冲行填充方法,避免头指针、尾指针和容量三个变量在同一个缓冲行中,造成伪共享问题。
5.根据权利要求1所述的无锁并发消息处理机制的实现方法,其特征在于:所述的环形数组长度设为2的指数倍,采用“与操作”的位运算代替“取余操作”来获取数组下标,利用计算机“与操作”的效率高于“取余操作”的特性来提高整体效率。
【文档编号】G06F9/38GK104077113SQ201410327258
【公开日】2014年10月1日 申请日期:2014年7月10日 优先权日:2014年7月10日
【发明者】袁浩, 曾令将 申请人:中船重工(武汉)凌久电子有限责任公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1