Linux内核数据结构(二)

队列


队列也是一种链表,只是针对队列的操作只能是从队尾插入,从队首删除。在操作系统中有很多这种数据结构的用武之地,一般是一个进程产生数据,另外一个进程处理数据,如Linux中网络数据包的处理,进程之间使用管道通信等,都是这种情况。Linux内核中队列称作kfifo,其对应的源文件时kernel/kfifo.c,<linux/kfifo.h>中包含了其声明。



kfifo提供了两种操作,入队(in)和出队(out),为了记录下一次出队或者入队的位置,kfifo维护了两个变量in和out。入队操作会将数据拷贝至队列中,具体位置由in确定,然后根据数据大小更新in,标识下一入队发生的位置。出队的操作与之类似。当in和out相等时,队列为空,此时不能执行出队操作。当in等于队列长度时,不能执行入队操作。


和其他内核对象一样,定义并初始化队列也有静态和动态两种方式。

动态方法


这个函数创建并初始化一个大小为size的队列。gfp_mask指定内存分配方式,可以取值GFP_KERNEL,GFP_ATOMIC,当在进程上下文分配内存,使用GFP_KERNEL,此时,允许kmalloc函数因为等待内存页释放而睡眠。如果,在中断上下文中分配内存,使用GFP_ATOMIC,此时kmalloc不能睡眠,此时可能由于内存不足导致分配失败。


如果,你想自己分配队列空间,可以使用下面这个函数。


这个函数创建并初始化kfifo,这个kfifo使用buffer指向的大小为size的区域作为队列节点存储区域。注意,size必须为2的n次方,即size = 2n


静态方法

DECLARE_KFIFO(name, size);

INIT_KFIFO(name);



入队

但kfifo成功创建后,就可以想队列尾部放入数据


这个函数将buf开始的n个字符插入队列。这里是尽最大努力的拷贝,也就是说如果空间不足,拷贝的大小就是可用空间可容纳的大小。


出队


这个函数从队列中读出长度为n的数据,然后放入以buf表示的缓冲区中。出队意味着以后数据已不在队列中,你也可以调用函数kfifo_out_peek来读取数据而不从队列中删除这些数据。对于队列的操作需要注意的就是同步的问题,因为这等效于读者和写者问题。有兴趣可以看看内核中的实现。


其他队列的操作还有很多,代码文件位于linux/kfifo.c以及include/linux/kfifo.h中。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值