并发无锁队列学习之二【单生产者单消费者】

简介:

1、前言

  

  最近工作比较忙,加班较多,每天晚上回到家10点多了。我不知道自己还能坚持多久,既然选择了就要做到最好。写博客的少了。总觉得少了点什么,需要继续学习。今天继续上个开篇写,介绍单生产者单消费者模型的队列。根据写入队列的内容是定长还是变长,分为单生产者单消费者定长队列和单生产者单消费者变长队列两种。单生产者单消费者模型的队列操作过程是不需要进行加锁的。生产者通过写索引控制入队操作,消费者通过读索引控制出队列操作。二者相互之间对索引是独享,不存在竞争关系。如下图所示:

2、单生产者单消费者定长队列

  这种队列要求每次入队和出队的内容是定长的,即生产者写入队列和消费者读取队列的内容大小事相同的。linux内核中的kfifo就是这种队列,提供了读和写两个索引。单生产者单消费者队列数据结构定义如下所示:

复制代码
typedef struct
{
    uint32_t r_index; /*读指针*/
    uint32_t w_index; /*写指针*/
    uint32_t size;    /*缓冲区大小*/
    char *buff[0];    /*缓冲区起始地址*/
}ring_buff_st;
复制代码

为了方便计算位置,设置队列的大小为2的次幂。这样可以将之前的取余操作转换为位操作,即r_index = r_index % size 与 r_index = r_index & (size -1)等价。位操作非常快,充分利用了二进制的特征。
(1)队列初始状态,读写索引相等,此时队列为空。

  

(2)写入队列

写操作即进行入队操作,入队有三种场景,

2.1 写索引大于等于读索引

2.2写索引小于读索引

2.3.写索引后不够写入一个

(3)读取队列

读队列分为三种场景

3.1写索引大于等于读索引

3.2写索引小于读索引

3.3.读索引后面不够一个

3、单生产者单消费者变长队列

  有些时候生产者每次写入的数据长度是不确定的,导致写入队列的数据时变长的。这样为了充分利用队列,需要增加一个结束索引,保证队列末尾至少能够写入一个数据。变长队列数据结构定义如下:

复制代码
typedef struct
{
    uint32_t r_index; /*读指针*/
    uint32_t w_index; /*写指针*/
    uint32_t e_index; /*队列结束指针*/
    uint32_t size;    /*缓冲区大小*/
    char *buff[0];    /*缓冲区起始地址*/
}ring_buff_st;
复制代码
相关文章
|
容器
多线程学习之生产者和消费者与阻塞队列的关系
多线程学习之生产者和消费者与阻塞队列的关系
59 0
|
8月前
|
数据处理
多线程与并发编程【线程对象锁、死锁及解决方案、线程并发协作、生产者与消费者模式】(四)-全面详解(学习总结---从入门到深化)
多线程与并发编程【线程对象锁、死锁及解决方案、线程并发协作、生产者与消费者模式】(四)-全面详解(学习总结---从入门到深化)
75 1
|
3月前
|
消息中间件 NoSQL 关系型数据库
【多线程-从零开始-捌】阻塞队列,消费者生产者模型
【多线程-从零开始-捌】阻塞队列,消费者生产者模型
37 0
|
5月前
|
Java
并发编程之生产者和消费者问题
该博客文章通过Java代码示例介绍了生产者和消费者问题的线程间通信解决方案,演示了如何使用synchronized关键字和wait/notifyAll方法来实现线程间的同步和资源的协调访问。
|
7月前
|
并行计算 安全 Go
可重入锁实现消费者和生产者的例子
【6月更文挑战第28天】本文探讨了Python和Go中使用可重入锁(RLock)进行线程同步以及异步操作。异步存取示例展示了goroutine的并发优势,启动简单且运行异步。goroutine的调度和并发处理能力是其高效并发的关键。
39 0
可重入锁实现消费者和生产者的例子
|
安全 Java
【JUC基础】06. 生产者和消费者问题
学习JUC,就不得不提生产者消费者。生产者消费者模型是一种经典的多线程模型,用于解决生产者和消费者之间的数据交换问题。在生产者消费者模型中,生产者生产数据放入共享的缓冲区中,消费者从缓冲区中取出数据进行消费。在这个过程中,生产者和消费者之间需要保持同步,以避免数据出现错误或重复。今天我们就来说说生产者消费者模型,以及JUC中如何解决该模型的同步问题。
154 0
|
缓存 Java 数据安全/隐私保护
JUC并发编程学习(四)-生产者与消费者
JUC并发编程学习(四)-生产者与消费者
JUC并发编程学习(四)-生产者与消费者
|
安全 Java
Java多线程——生产者/消费者问题
生产者/消费者问题
169 0
|
安全 算法 Java
【并发容器精讲三、】并发队列Queue
1. 为什么要使用队列 - 用队列可以在线程间传递数据:生产者,消费者模式,银行转帐 - 考虑锁等线程安全问题重任 转移到队列上 # 2. 并发队列简介 简单介绍各个并发并发队列的关系,并发队列是指线程安全的队列,包含:阻塞队列和非阻塞队列
826 0
【并发容器精讲三、】并发队列Queue

热门文章

最新文章