队列操作模型
(1)单生产者——单消费者
(2)多生产者——单消费者
(3)单生产者——多消费者
(4)多生产者——多消费者
3、队列数据定长与变长
(1)队列数据定长
(2)队列数据变长
并发无锁处理
(1)单生产者——单消费者模型
此种场景不需要加锁,定长的可以通过读指针和写指针进行控制队列操作,变长的通过读指针、写指针、结束指针控制操作。具体实现可以参考linux内核提供的kfifo的实现。可以参考:
http://blog.csdn.net/linyt/article/details/5764312
(2)(一)多对多(一)模型
正常逻辑操作是要对队列操作进行加锁处理。加锁的性能开销较大,一般采用无锁实现。无锁实现原理是CAS、FAA等机制。定长的可以参考:
http://coolshell.cn/articles/8239.html
变长的可以参考intel dpdk提供的rte_ring的实现。
http://blog.csdn.net/linzhaolover/article/details/9771329
原文:https://www.cnblogs.com/alantu2018/p/8469168.html
无锁队列的实现
关于无锁队列的实现,网上有很多文章,虽然本文可能和那些文章有所重复,但是我还是想以我自己的方式把这些文章中的重要的知识点串起来和大家讲一讲这个技术。下面开始正文。
1. 什么是无锁队列
字面意思理解,就是两个线程同步操作某种数据时,不能加锁;
因为加锁是会拖慢效率,造成延时的;
2. 什么场景需要用到无锁队列呢?
最典型的是生产者和消费者模型,要求生产者生产的同时,进行消费,这就要求足够的低延时,此时可以使用无锁队列;
比如:
线程A生产 1,2,3,4...
线程B对生产出来的数相加,要求效率足够高,不能用锁,此时就可以用无锁队列。
3. 无锁队列的实现
#define MAX_NUMBER 1000
#define OK 0
#define ERROR -1
typedef struct _QUEUE_DATA
{
int iData[MAX_NUMBER];
int head;
int tail;
}QUEUE_DATA;
QUEUE_DATA* pHead = new QUEUE_DATA;
pHead->head = 0;
pHead->tail = 0;
//从队尾加入数据,队列是一个环形队列
int push_data(QUEUE_DATA* pHead, int data)
{
if ( pHead == NULL || (pHead->head == ((pHead->tail +1) % MAX_NUMBER) ) )
{
return ERROR;
}
pHead->iData[pHead->tail] = data;
pHead->tail = (pHead->tail+1)%MAX_NUMBER;
return OK;
}
int pop_data(QUEUE_DATA* pHead)
{
if (pHead == NULL || (pHead->head == pHead->tail))
{
return ERROR;
}
pHead->iData[pHead->head] = 0;
pHead->head = (pHead->head+1)%MAX_NUMBER;
return OK;
}