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猿”找到小猿哦!!!