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

Linux驱动开发进阶(五)- 系统调用

文章目录

  • 1、前言
  • 2、阻塞与非阻塞IO
    • 2.1、阻塞方式
    • 2.2、非阻塞方式
    • 2.3、小结
  • 3、异步IO
    • 3.1、poll
    • 3.2、select
    • 3.3、epoll
    • 3.4、poll和epoll示例比较
    • 3.5、异步通知
  • 4、unlocked_ioctl
  • 5、sysfs_notify

1、前言

  1. 学习参考书籍以及本文涉及的示例程序:李山文的《Linux驱动开发进阶》
  2. 本文属于个人学习后的总结,不太具备教学功能。

2、阻塞与非阻塞IO

2.1、阻塞方式

用户程序调用read系统调用时,从用户态切换到内核态。内核检查设备是否准备好数据,如果设备尚未准备好数据,内核会将当前进程标记为“阻塞”状态,并将其放入等待队列中,同时进入休眠状态。当设备准备好数据时,内核会将等待队列中的进程唤醒。内核从设备读取数据,并将数据复制到用户空间。系统调用返回,用户程序继续执行。

相关示例程序可以参考:https://gitee.com/li-shan-asked/linux-advanced-development-code/tree/master/part5/block_io

重点宏或函数如下:

init_waitqueue_head(wq_head)
wait_event_interruptible(wq_head, condition)
wake_up_interruptible(x)

2.2、非阻塞方式

非阻塞方式和阻塞方式相比,当用户程序调用read系统调用时,如果设备尚未准备好数据,直接返回错误。此时可以继续发起read系统调用。

相关示例程序可以参考:https://gitee.com/li-shan-asked/linux-advanced-development-code/tree/master/part5/nonblokck-io

2.3、小结

所以阻塞方式不会占用cpu资源,适合对实时性不高的场景。非阻塞方式需要不断轮询,可能会增加cpu负载,适合高并发场景。

3、异步IO

3.1、poll

poll可以说是对阻塞IO的一种改进。我们知道阻塞IO中,如果设备状态一直不可用,那么应用程序会一直休眠。而poll机制中,就是增加了超时机制。当一段时间内设备还是不可用,则强行调度,将应用程序唤醒。

作为驱动开发者,需要实现poll驱动的回调函数。

static __poll_t key_poll(struct file *file, poll_table *wait)
{
    poll_wait(file, &key->wait_head, wait);
    if (key->ev_press == 1)
        return EPOLLIN | EPOLLRDNORM;
    return EPOLLOUT | EPOLLWRNORM;
}

static struct file_operations key_ops = {
    ...
    .poll = key_poll,
    ...
};

相关示例程序可以参考:https://gitee.com/li-shan-asked/linux-advanced-development-code/tree/master/part5/poll

3.2、select

poll机制和select机制是一样的,应用程序调用select系统调用时,最终调用的还是内核驱动程序中的poll函数。所以主要了解应用程序中的select系统调用即可。

相关示例程序可以参考:https://gitee.com/li-shan-asked/linux-advanced-development-code/tree/master/part5/select

3.3、epoll

当fd数量小于1000时,使用poll和select还算合适。因为poll和select每次调用时都需要遍历所有监听的fd,检查他们的就绪状态,例如,监听10000个fd,即使只有1个fd就绪,也需要遍历全部10000个,效率极低。

而epoll适用于有大量的描述符需要同时轮询,并且这些连接最好是长连接。用户空间的应用程序调用epoll相关接口,最终还是调用内核的poll接口。

相关示例程序可以参考:https://gitee.com/li-shan-asked/linux-advanced-development-code/tree/master/part5/epoll

3.4、poll和epoll示例比较

poll的低效实现:

// 每次需遍历所有 FD
struct pollfd fds[10000];
while (1) {
    int ret = poll(fds, 10000, 1000);  // O(n) 遍历
    for (int i = 0; i < 10000; i++) {  // 再次遍历检查
        if (fds[i].revents & POLLIN) {
            // 处理就绪 FD
        }
    }
}

epoll的高效实现:

int epfd = epoll_create1(0);
struct epoll_event ev, events[100];

// 注册 FD(首次拷贝到内核)
ev.events = EPOLLIN | EPOLLET;  // ET 模式
epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);

while (1) {
    int nready = epoll_wait(epfd, events, 100, 1000);  // 仅返回就绪 FD
    for (int i = 0; i < nready; i++) {                 // 直接处理
        // 处理 events[i].data.fd
    }
}

epoll是Linux特有的,注意跨平台限制。

3.5、异步通知

上面介绍的poll/select、epoll还是需要主动去查询设备是否可用,大多数情况下,设备都是不可用的。所以是否还有更好的方式,那就是异步通知,当设备可用时,内核驱动程序主动向应用程序发起通知。

可以参考以前写的:I/O管理:异步通知

同时相关示例程序可以参考:https://gitee.com/li-shan-asked/linux-advanced-development-code/tree/master/part5/async

4、unlocked_ioctl

ioctl是旧版本的内核API,需要持有大内核锁。unlocked_ioctl是现代内核中推荐使用的API,它不需要持有大内核锁,从而提高了性能和灵活性。

相关示例程序可以参考:https://gitee.com/li-shan-asked/linux-advanced-development-code/tree/master/part5/ioctl

5、sysfs_notify

当用户空间使用poll、select、epoll接口检测一个sysfs目录下的属性文件时,此时如果内核不做任何动作,则用户空间中的进程就会被阻塞起来,当内核中调用sysfs_notify函数时,此时用户空间的进程被唤醒,就可以执行相应的动作。

sysfs_notify函数实现如下:

最终会调用kernfs_notify(),最终调用wake_up_interruptible:

相关示例程序可以参考:https://gitee.com/li-shan-asked/linux-advanced-development-code/tree/master/part5/sysfs_notify

相关文章:

  • Logo语言的死锁
  • 【C++】类和对象 (第一弹)
  • 处理语言模型返回的响应
  • 【Survival Analysis】【机器学习】【1】
  • Android 11.0 framework系统首次开机添加锁屏壁纸的功能
  • Go语言报错总结(文章持续更新)
  • 洛谷蓝桥杯刷题
  • CRC校验码的检错性能(三)——基于对偶码重量分布计算漏检概率
  • STM32江科大----IIC
  • 004 Vue Cli脚手架(vue2)
  • 在CentOS上安装Docker需要注意的事项
  • 基于Arduino的ESP8266连接OneNET云平台(MQTT协议 物模型)(一)ESP8266固件烧录
  • Solidity基础入门—web3
  • GitHub 趋势日报 (2025年04月06日)
  • MATLAB中movmin函数用法
  • Python爬虫第5节-urllib的异常处理、链接解析及 Robots 协议分析
  • 深度探索:策略学习与神经网络在强化学习中的应用
  • WHAT - JavaScript 中 Object.defineProperty() 和 Proxy 对比
  • 使用LangChain Agents构建Gradio及Gradio Tools(4)——Gradio Tools:gradio_tools库
  • 小刚说C语言刷题——第17讲 循环之for语句
  • wordpress hosts/百度seo推广方案
  • 卡通型网站/营销咨询
  • 什么网站可以做旅行行程单/域名服务器ip地址查询
  • 网站网页设计师/网络营销有什么岗位
  • 网站外链平台/平台运营
  • 合肥快速建站模板/网页制作成品模板网站