zoukankan      html  css  js  c++  java
  • 并发无锁队列学习(单生产者单消费者模型)

    1、引言
    本文介绍单生产者单消费者模型的队列。依据写入队列的内容是定长还是变长,分为单生产者单消费者定长队列和单生产者单消费者变长队列两种。

    单生产者单消费者模型的队列操作过程是不须要进行加锁的。生产者通过写索引控制入队操作,消费者通过读索引控制出队列操作。二者相互之间对索引是独享,不存在竞争关系。

    例如以下图所看到的:
    这里写图片描写叙述
    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、单生产者单消费者变长队列

      有些时候生产者每次写入的数据长度是不确定的,导致写入队列的数据时变长的。这样为了充分利用队列。须要添加一个结束索引,保证队列末尾至少可以写入一个数据。变长队列数据结构定义例如以下:
      具体见我博客关于边长数组介绍

    http://blog.csdn.net/xy010902100449/article/details/46522533
     

    typedef struct
    {
        uint32_t r_index; /*读指针*/
        uint32_t w_index; /*写指针*/
        uint32_t e_index; /*队列结束指针*/
        uint32_t size;    /*缓冲区大小*/
        char *buff[0];    /*缓冲区起始地址*/
    }ring_buff_st;
  • 相关阅读:
    Linux的僵尸进程及其解决方法
    描述linux系统从开机到登陆界面的启动过程
    __weak、__strong这样的关键词和weak、strong有哪些区别
    选择器(UIPickerView)
    UITableView 滚动流程性优化
    几种设置UITableView的cell动态高度的方法
    强大的Core Image(教你做自己的美图秀秀))
    iOS UIBezierPath类 介绍
    Quartz 2D编程指南- PDF文档的创建、显示及转换
    Quartz 2D编程指南(4) - 颜色和颜色空间
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/7353062.html
Copyright © 2011-2022 走看看