当前位置: 首页 > news >正文

kfifo

1. kfifo (内核 FIFO)

kfifo 是 Linux 内核中一个通用、无锁(在单读者单写者场景下)的环形缓冲区实现。它设计精巧,提供了简洁而强大的 API。

主要特性:

  • 无锁(特定条件下):当只有一个生产者和一个消费者时,kfifo 是无锁的,性能极高。这是通过分离生产者和消费者的索引指针实现的。
  • 内存高效:其内部缓冲区的大小通常要求是 2 的幂次方。这使得可以通过位运算(如 & (size - 1))来高效计算回绕索引,而不是昂贵的取模运算。
  • 健壮的 API:提供了用于入队(Enqueue)和出队(Dequeue)的核心函数,这些函数会返回成功操作的数据量,便于处理。
  • 动态和静态分配:支持在编译时静态分配或在运行时动态分配内存。
  • 处理任意大小数据:可以处理任意字节序列,而不仅仅是固定大小的元素。

核心 API(位于 <linux/kfifo.h>):

  • 初始化和销毁

    • int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask):动态分配并初始化一个 kfifo。
    • void kfifo_free(struct kfifo *fifo):释放由 kfifo_alloc 分配的 fifo。
    • void kfifo_init(struct kfifo *fifo, void *buffer, unsigned int size):使用用户提供的预分配缓冲区来初始化 kfifo。
  • 入队(写操作)

    • unsigned int kfifo_in(struct kfifo *fifo, const void *buf, unsigned int len):将数据从用户缓冲区 buf 写入 fifo,最多写入 len 字节。返回实际写入的字节数。
    • int kfifo_in_spinlocked(struct kfifo *fifo, const void *buf, unsigned int n, spinlock_t *lock):在需要自旋锁保护的情况下使用的变体。
  • 出队(读操作)

    • unsigned int kfifo_out(struct kfifo *fifo, void *buf, unsigned int len):从 fifo 中读取数据到用户缓冲区 buf,最多读取 len 字节。返回实际读取的字节数。数据会被从 fifo 中移除。
    • unsigned int kfifo_out_peek(struct kfifo *fifo, void *buf, unsigned int len, unsigned offset):窥视 fifo 中的数据而不将其移除。
    • int kfifo_out_spinlocked(struct kfifo *fifo, void *buf, unsigned int n, spinlock_t *lock):在需要自旋锁保护的情况下使用的变体。
  • 状态查询

    • unsigned int kfifo_size(struct kfifo *fifo):返回 fifo 的总容量。
    • unsigned int kfifo_len(struct kfifo *fifo):返回 fifo 中当前已用的字节数。
    • unsigned int kfifo_avail(struct kfifo *fifo):返回 fifo 中剩余的可用空间字节数。
    • bool kfifo_is_empty(struct kfifo *fifo) / bool kfifo_is_full(struct kfifo *fifo):检查 fifo 是否为空或满。

使用示例:

#include <linux/kfifo.h>#define MY_FIFO_SIZE 1024 // 必须是 2 的幂struct my_device_data {struct kfifo data_fifo;spinlock_t fifo_lock; // 如果有多生产者/多消费者则需要
};static int my_probe_function(struct device *dev) {struct my_device_data *data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);int ret;// 动态分配并初始化 kfiforet = kfifo_alloc(&data->data_fifo, MY_FIFO_SIZE, GFP_KERNEL);if (ret) {return ret;}spin_lock_init(&data->fifo_lock);// ... 其他初始化return 0;
}// 生产者端
ssize_t my_write_function(struct my_device_data *data, const char __user *user_buf, size_t count) {unsigned int copied;unsigned long flags;spin_lock_irqsave(&data->fifo_lock, flags);copied = kfifo_in(&data->data_fifo, user_buf, count);spin_unlock_irqrestore(&data->fifo_lock, flags);// 可能唤醒等待数据的读者wake_up_interruptible(&my_read_queue);return copied;
}// 消费者端
ssize_t my_read_function(struct my_device_data *data, char __user *user_buf, size_t count) {unsigned int copied;unsigned long flags;spin_lock_irqsave(&data->fifo_lock, flags);copied = kfifo_out(&data->data_fifo, user_buf, count);spin_unlock_irqrestore(&data->fifo_lock, flags);return copied;
}

2. 其他环形缓冲区实现

除了通用的 kfifo,内核中还有其他一些特定用途的 Ring Buffer:

  • perf 子系统:Linux 的性能分析(perf)子系统使用了一个高度优化的环形缓冲区(kernel/events/ring_buffer.c)来将性能计数器数据从内核态高效地传递到用户态。
  • Trace Ring Buffer:内核的 Ftrace 跟踪框架使用了自己实现的环形缓冲区来存储跟踪事件。这个实现非常复杂,考虑了每 CPU 缓冲区、时间戳、并发写入等。
  • DMA 环形缓冲区:许多网络和存储设备驱动使用环形缓冲区来描述 DMA(直接内存访问)描述符环。例如,在网卡驱动中,经常可以看到 rx_ringtx_ring,用于管理接收和发送的数据包缓冲区。

总结

实现主要用途特点
kfifo通用环形缓冲区无锁(SPSP场景)、API简洁、内存高效,是大多数情况下的首选
perf ring buffer性能事件数据内核到用户空间的高性能数据传递,与 perf 工具紧密集成
trace ring buffer内核跟踪每 CPU 缓冲区,用于系统调试和性能分析
DMA descriptor ring设备驱动(网络、存储)管理硬件 DMA 操作,与设备寄存器交互

因此,当你在 Linux 内核开发中需要一个环形缓冲区时,首先应该考虑 kfifo。它经过了充分的测试和优化,能够满足绝大多数场景的需求,并且可以避免重复造轮子。只有在 kfifo 无法满足特定性能或功能要求时,才需要考虑实现自定义的环形缓冲区或使用其他特定子系统的实现。

http://www.dtcms.com/a/488587.html

相关文章:

  • 广州天河区网站建设怎么地wordpress
  • wordpress网站被拒登企业官网招聘
  • 【时时三省】(C语言基础)用格式化的方式读写文本文件
  • 国外 网站 模板广州建站哪个济南兴田德润实惠吗
  • 网站快速收录工具医疗器械类网站icp备案前置审批
  • 济南 网站推广制作公司网站设计要求
  • 曲靖网站微信建设百度指数分析数据
  • 遵义专业网站建设公司电话前端代码大全
  • 上海注册公司多久义乌网站建设优化排名
  • 网站上做百度广告赚钱么泰安人才网招聘网
  • 从零开始读懂Transformer:架构解析与PyTorch实现
  • 网站备案核验单酒店网站制作策划
  • 宁夏建设厅网站领导做平台网站要什么条件
  • 去别人网站挂黑链西地那非可以长期吃吗
  • 怎么做二维码微信扫后直到网站php做网站的源码
  • ASP 总结
  • 企业需求做网站在哪儿交易对网站开发语言的统计
  • 江西住房和城乡建设部网站首页东莞高森网络营销
  • 网站优化包括郑州seo优化顾问
  • C++ 重载运算符和重载函数
  • 杭州桐庐网站建设做两个网站 之间超链接
  • 怎样建设好门户网站宜春网站设计公司
  • 南通网站制作公司哪家好网站制作的相关术语有哪些
  • 做网站需要多少钱呢专业团队黑人
  • 温州网站建设服务温州建网站业务人员
  • 网站推广设计呼和浩特市网站
  • DOM 删除节点
  • QuickBI VS FineBI设置警戒线,QuickBI功能更全
  • 模型剪枝详解(一):认识剪枝
  • 网站建设技术教程视频洛阳直播网站建设