队列适合于生产者和消费者的编程模型中。在该模型中,生产者创造数据,消费者则读取并处理数据。Linux内核通用队列由kfifo实现。它实现在文件kernel/kfifo.c中,声明在<linux/kfifo.h>中。这里分析的是内核版本2.6.35.3的kfifo。
一、kfifo原理
kfifo实现原理是采用循环(环形)队列。关于循环(环形)队列请自行百度或参考数据结构的书籍。
二、kfifo特点
kfifo的设计颇具技巧性,总结有以下几大特点:
1、采用环形缓冲区来实现,提供一个无边界的字节流服务。采用环形缓冲区的好处为,当一个数据元素被用掉后,其余数据元素不需要移动其存储位置,从而减少拷贝提高效率。
2、保证缓冲区大小为2的次幂,不是的向上取整为2的次幂。
3、使用无符号整数保存输入(in)和输出(out)的位置,在输入输出时不对in和out的值进行模运算,而让其自然溢出,并能够保证in-out的结果为缓冲区中已存放的数据长度。
4、将需要取模的运算用 & 操作代替( a % size = (a & (size − 1)) ), 这需要size保证为2的次幂。
5、使用内存屏障(Memory Barrier)技术,实现单消费者和单生产者对kfifo的无锁并发访问(包括多CPU的情况),多个消费者、生产者的并发访问还是需要加锁的。关于kfifo中内存屏障的使用,请参考https://www.linuxidc.com/Linux/2016-12/137936.htm。
三、kfifo功能函数
1、创建队列