首页 > 编程知识 正文

linux内核最早是由谁开发的,内核缓冲区 用户缓冲区

时间:2023-05-04 07:33:42 阅读:120066 作者:348

8种机械键盘轴体的比较

本人,买写代码的键盘,红轴和茶轴怎么选?

万丈高楼以地基牢固为前提。

环形缓冲区

介绍

“圆形缓冲区”(circular buffer )也被称为“圆形队列”(circular queue )、“循环缓冲区”(cyclic buffer )和“环形缓冲区”(ring buffer ),适用于缓存数据流

使用方法

圆形缓冲区的一个有用特性是使用了一个数据元素后,其馀的数据元素不需要移动存储位置。 相反,在非圆形缓冲区(如常规队列)中,使用数据元素后,必须向前移动其馀的数据元素。 换句话说,圆形缓冲器适合于实现先进先出缓冲器,而不是圆形缓冲器。

圆形缓冲器适用于事先明确缓冲器的最大容量的情况。 要扩展圆形缓冲区的容量,必须移动其中的数据。 因此,如果需要频繁调整一个缓冲区的容量,最好在链表中实现。

在某些情况下,允许执行复盖圆形缓冲区中未处理数据的操作。 特别是在多媒体处理的时候。 例如,音频生产者可以覆盖声卡还不能处理的音频数据。

工作过程

圆形缓冲区最初为空,有规定的长度。 例如,这是一个具有七个元素空间的圆形缓冲区,底部的单线和箭头表示“头尾相连”,从而形成圆形地址空间。

假设1已写入缓冲区中间。 对于圆形缓冲区,第一个写入位置可以是任何位置。

再写入两个要素,分别追加在2 3 —之后:

处理两个元素时,将卸载缓冲区中最旧的两个元素。 在此实例中,1 2被卸载且缓冲器中只剩下333到360

如果缓冲区中有7个元素,则已满。

缓冲区已满,要写入新数据,您可以选择复盖最旧的数据。 在本示例中,两个新数据——ab -写入,涵盖了3 4:

也可以采取其他策略,禁止复盖缓冲区中的数据、返回错误代码或抛出异常。

最终,如果从缓冲区卸载两个数据,将是5 6,而不是3 4。 因为A B已经涵盖了3 4 :

圆形缓冲器的结构

由于计算机存储器是线性地址空间,圆形缓冲区需要特殊设计才能逻辑实现。

读取指针和写入指针

圆形缓冲区通常需要四个指针。 存储器内实际开始位置;

存储器中的实际结束位置也可以用缓冲长度代替;

缓冲区中存储的有效数据的开始位置(读取指针);

存储在缓冲区中的有效数据的最后一个位置(写入指针)。

读取指针、写入指针可以用整数值表示。

以下示例是指向缺少缓冲区的读/写指针。

以下示例是一个充满缓冲区的读写指针。

根据区分缓冲区是满还是空的缓冲区是满还是空,读取指针和写入指针可能指向同一个位置。

250px提供了多种方法来检测缓冲区是满还是空。

始终将一个存储单元保留为空

缓冲区中始终有一个存储单元保持未使用状态。 缓冲区最多存储一个数据。 如果读/写指针指向同一位置,则缓冲区为空。 如果写入指针位于读取指针旁边,则缓冲区将填满。 该策略的优点是简单、鲁棒的缺点是,在语义上测试实际存储的数据量和缓冲区容量是否不匹配,是否需要填满缓冲区进行剩余计算。

使用数据计数

此策略不使用显式写入指针,而是保留缓冲区中存储的数据的计数。 因此,测试缓冲区为空非常简单。 对性能的影响可以忽略不计。 缺点是,必须在读写操作中更改此保存数据数,并且必须同时控制多线程访问缓冲区。

镜像指示位

缓冲区长度为n时,逻辑地址空间为0到n-1。 那么,将n到2n-1作为镜像逻辑地址空间。 该策略规定读/写指针的地址空间为2n-1,下半部分对应于正常逻辑地址空间,上半部分对应于镜像逻辑地址空间。 指针值为2n以上时,折回ptr-2n。 使用指示写指针或读指针是否进入虚拟镜像库的位。 套装表示进入,不套装表示还没有进入基本银行。

在读写指针值相同的情况下,如果两者的指示位相同,则缓冲器为空; 如果两者的指示位不同,则表示缓冲区已满。 这种方法的优点是测试缓冲区的空闲/空闲很容易;不需要额外的操作; 读写线程可以分别设计专用的算法策略,实现精细的并发控制。 缺点是,读写指针分别需要附加的位作为指示位。

在缓冲器长度为2的幂的情况下,本技术可以省略镜像指示位。 如果读/写指针的值相等,则缓冲区为空。 读写指针n不同,缓冲区就满了。 这可以通过表达式(写入指针==)读取指针异或缓冲区长度)来判断。

读取/写入次数

p>用两个有符号整型变量分别保存写入、读出缓冲区的数据数量。其差值就是缓冲区中尚未被处理的有效数据的数量。这种方法的优点是读线程、写线程互不干扰;缺点是需要额外两个变量。

记录最后的操作

使用一位记录最后一次操作是读还是写。读写指针值相等情况下,如果最后一次操作为写入,那么缓冲区是满的;如果最后一次操作为读出,那么缓冲区是空。 这种策略的缺点是读写操作共享一个标志位,多线程时需要并发控制。

POSIX优化实现

Linux内核的kfifo

在Linux内核文档kfifo.h和kfifo.c中,定义了一个先进先出圆形缓冲区实现。如果只有一个读线程、一个写线程,二者没有共享的被修改的控制变量,那么可以证明这种情况下不需要并发控制。kfifo就满足上述条件。kfifo要求缓冲区长度必须为2的幂。读、写指针分别是无符号整型变量。把读写指针变换为缓冲区内的索引值,仅需要“按位与”操作:(指针值 按位与 (缓冲区长度-1))。这避免了计算代价高昂的“求余”操作。且下述关系总是成立:

读指针 + 缓冲区存储的数据长度 == 写指针即使在写指针达到了无符号整型的上界,上溢出后写指针的值小于读指针的值,上述关系仍然保持成立(这是因为无符号整型加法的性质)。 kfifo的写操作,首先计算缓冲区中当前可写入存储空间的数据长度:len = min[待写入数据长度, 缓冲区长度 - (写指针 - 读指针)]然后,分两段写入数据。第一段是从写指针开始向缓冲区末尾方向;第二段是从缓冲区起始处写入余下的可写入数据,这部分可能数据长度为0即并无实际数据写入。

扫描以下公众号关注小猿↓↓↓↓↓↓↓↓

更多资讯请在简书、微博、今日头条、掘金、CSDN都可以通过搜索“Share猿”找到小猿哦!!!

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。