【操作系统】中断、驱动程序与 signal 处理函数

中断是 cpu 与外设打交道的重要方式。计算机有多重多样的外设,例如:键盘、鼠标、硬盘、显示器等。除了 cpu 向这些外设传输数据外,这些设备也会向 cpu 传输数据。学习后发现,中断的理解与驱动程序的理解关系密切。并且中断与信号处理函数有很大的相似性,本文将讨论这三者的相关问题。

cpu 与外设的速度差别有多大

cpu 运行效率比较快,主流的 cpu 目前都能轻松达到 4GHz 以上的频率,再乘以 IPC,cpu 每秒处理的指令在 40亿 量级。换个单位,cpu 每毫秒都要处理 4千万条指令。相比之下,设备确实是太慢了。而鼠标回报率大概1000Hz。也就是说,鼠标也是1毫秒向cpu发送一次中断,假设处理一次中断需要1000条指令。那么 cpu 相当于只用了少于万分之一的时间来处理鼠标的终端。

除了中断还有没有别的外设通讯方式?

中断是外设主动请求与 cpu 通讯的唯一方式。但外设太多,或者一些特殊外设需要更频繁的数据传输,还有另外两种方式。

  1. 优化中断频率:DMA 就是针对网卡这种大量频繁传输数据的场景的优化。只需要在 cpu 给网卡分配一段内存,网卡通过 DMA 直接在内存上操作,等内存满了,再向 cpu 请求中断。这样可以大大减少中断次数,但是会略微增加时延。
  2. 轮询(poll):外设不中断 cpu,而是设置一个专用寄存器。cpu 隔一段时间就查看一下该寄存器状态,来判断是否有需要处理的外设。问题是 cpu 何时来执行这段轮询代码是一个问题,对应到程序中就是,代码写在哪里不好设计。而且如果需要轮询的外设过多,反而会造成比较大的浪费。在内核中,可以在每次用户态陷入内核的时候,执行一小段轮询来处理。比如:线程切换时,花点时间轮询设备。

有哪些典型需要中断来处理的协议

设备一般不会与 cpu 直接通讯,而是由一个专用的通讯模块代劳。各个设备委托这个模块帮忙通讯。而这个通讯模块通常也叫做总线。它之上会挂在一系列设备,遵循一定的协议,并在适当的时候向 cpu 请求中断

  • 串口通讯:usb、uart、i2c、spi
  • 总线协议:pci、pcie

中断处理流程

  1. 设备发出中断请求。
  2. 中断控制器接受信号,并按照操作系统内核编写的程序,分配一个 cpu 核心去处理该中断。
  3. cpu 在合适的时候,在内核态,执行中断处理程序(驱动的 bottom 部分)
  4. 执行完之后恢复 cpu 之前的状态。

设备驱动程序

对于驱动程序,容易理解的角度,是在计算机上,想控制设备需要调用的代码。往往由设备厂商提供 c/c++ 的库和接口供用户使用。
实际上上述理解角度只是驱动程序的一部分,通常称之为 Top。而还有一部分 bottom,正是 中断处理流程的第三步所描述的。
所以,设备驱动程序通常都会分为两部分

  1. top 部分由用户主动调用
  2. bottom 部分由 cpu 处理设备中断时调用,用户无需关心。

signal 处理函数

操作系统为了保证性能,总是会将内核中能够使用的一些机制也透传给用户态。例如:内核使用的页表,就通过 mmap 接口暴露给用户态使用。中断也不例外。与中断对应的用户态能力就是 signal 函数。

编写正确的中断处理函数是很困难的。同理,编写正确的信号处理函数也很困难。这一点在 csapp 书中提到过。陈硕在 muduo 库一书中更是明确表明:不要用信号处理函数。
中断处理程序的编写要避免讨厌的并发问题,因此通常在访问共享程序时要禁用中断。中断处理是由设备随时打断执行的,不能保证主程序此时没有持有锁。如果主程序持有锁,中断处理程序也想持有锁,那么就会发生死锁。信号处理函数也是一样。所以内核中的自旋锁在持有锁时,往往要先禁用中断。

摘抄 csapp 中编写正确信号处理函数需要的注意事项

  1. 安全的信号处理
    • 注意常规的线程安全问题
    • 处理程序尽可能简答
    • 调用的函数,必须是异步信号安全的。这样的函数满足以下两个特点之一:1. 可重入函数。2. 不可被信号处理程序中断(相当于禁用中断),
    • 保存 errno 变量
    • 所有访问共享数据结构的程序,无论是主程序还是信号处理程序都要阻塞所有信号。(相当于禁用中断)
    • 共享数据用 volatile 声明
    • 共享数据访问要加锁,或者使用原子变量来保证并发正确性 (c 语言中的 sig_atomic_t)
  2. 注意信号不排队问题,无论连续发送多少次信号,在第一个信号没处理之前,相当于只触发一次。类似于边缘触发。如果连续触发了两次,在信号处理函数中,最好将所有事件都处理掉,而不是只处理一次。
  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值