char-device-update

字符设备的改进

增加并发 解决竞态

可用技术方案

  • 屏障

  • 中断屏蔽

  • 原子操作

  • 互斥体 以进程为竞争单位

    不适用于以下情况

    • 出现中断或者软中断–>spin_lock_irq(),spin_lock_irqsave()
    • 频繁的切换
    • 临界区占用时间过短
  • 信号量 教科书经典定义,现在更推荐**互斥体**

  • 自旋锁 貌似以CPU为竞争资源(默认禁止本地cpu抢占)

    • 顺序锁seq-lock

    • 读写锁

    • 不适用于包含如下情况

      • 引起阻塞的代码
      • 临界区过大
      • 长时间占用临界区
    • 注意事项
      多核SMP情况下,任何一个核拿到了自旋锁,该核上的抢占调度就暂时禁止。但仍可能受到中断和**底半部(BH)**影响。
      多核SMP编程中,如果进程和其中断进程可能会范围同一临界区,则需要在进程中调用spin_lock_irq(),中断上下文中调用spin_lock()

    • 总结

      • spin_lock()可以禁止本地CPU的抢占,已及其他CPU的竞争
      • spin_lock_irq()可以进一步的禁止本地CPU的中断
      • spin_lock_irqsave()进一步增加一个保存中断开启状态,即在关闭本地中断之前禁止中断,如果能够确保没有其他代码禁止本地CPU的中断,则可以使用上一个函数。
  • RCU (Read-Copy-Update)

  • 完成量 Completion

情况分析

  1. tdlcd中,读写函数中,存在着可能阻塞的系统调用如copy_from_user等函数;如果选择自旋锁,在获得锁之后,阻塞在此类函数上,系统切换到调用函数,且也在等待占有这个锁,可能会引发死锁。所以选用互斥体 其实更好的选择应该是信号量semphore

阻塞操作 wait-queue

轮询操作 select,poll,epoll

应用程序中的select函数

int select(int numfds,fd_set *readfds,fd_set *writefds,fd_set *exceptfds,struct timval *timeout)
numfds为需要检查的最高文件描述符+1,档任何一个文件描述符变得可写可读时,select返回。
没有文件描述符满足要求时,select进程保持睡眠(阻塞)
实际上调用select时,每个驱动的poll接口被调用,即select进程被挂到了每个驱动的等待队列上。
一般来说,少量fd使用select.反之,epoll

poll函数

unsigned int (*poll)(struct file *filp),struct poll_table *wait)

两个参数分别为文件结构体指针,和轮询表指针。

  1. 对可能引起设备文件状态变化的等待队列调用poll_wait(不会引起阻塞)函数,将对应等待队列加入到轮询表中。 实际作用是让等待队列唤醒因select而睡眠的进程

  2. 返回表示是否能对设备进行无阻塞读写访问的掩码。

异步通知及异步IO

异步通知:信号驱动的异步I/O

  • 通过F_SETDIWB命令控制设备文件的拥有者

  • 通过F_SETFL命令设置设备文件以支持FASYNC

  • 通过signal函数连接信号和信号处理函数

07-tdlcd-async.jpg

git diff for async

异步I/O

Linux常见情况为同步I/O,即发出请求之后,应用程序便会阻塞直到请求得到响应。且在等待时不需要占用CPU

爬虫是不是这样的例子?

异步I/O则要么过一段时间来查询之前I/O请求完成情况,要么I/O请求完成了会自动调用完成绑定的回调函数

实际上阻塞I/O是同步的。

Linux 异步I/O在内核中得到了实现。

对于块设备,AIO可以一次性发出大量读写调用,然后通过通用块层的调度来实现更好的吸能。用户程序也可以减少过多的同步负载,在业务逻辑层更灵活的进行并发控制和负载均衡。
由于相较于用户空间的glibc多线程同步实现,减少了线程的负载和潜在的上下文切换。
sudo apt-get install libaio-dev

中断与定时器

为了在中断执行时间尽量短和中断处理需完成的工作量大之间找到平衡,Linux将中断处理程序分为两个半步:Top Half Bottom Half.

顶半部通常只完成读取状态,登记等工作,且一般不可被中断。

底半部机制主要有tasklet,工作队列,软中断,线程化irq

  • [ ] 机制未了解
  • [x] 待做事项测试

一个基于软中断的秒设备

内存映射

Author: hjl
Link: https://huqianshan.github.io/Linux/Drivers/char-device-update/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.