本文简介:
在设备驱动中使用异步通知可以使得对设备的访问可进行时,由驱动主动通知应用程序进行访问。这样,使用无阻塞I/O的应用程序无须轮询设备是否可访问,而阻塞访问也可以被类似“中断”的异步通知所取代。
9.1节讲解了异步通知的概念和作用,9.2节讲解了Linux异步通知的编程方法,9.3节讲解了增加了异步通知的globalfifo驱动及其在用户空间的验证。
9.1 异步通知的概念与作用
阻塞与非阻塞访问、poll()函数提供了较好的解决设备访问的机制,但是如果有了异步通知整套机制就更加完整了。
异步通知的意思是:一旦设备就绪,则主动通知应用程序,这样应用程序根本就不需要查询设备状态,这一点非常类似硬件上“中断的概念”,比较准确的称谓是“信号驱动的异步I/O”。信号是软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。
阻塞I/O意味着一直等待设备可访问后再访问,非阻塞I/O中使用poll()意味着查询设备是否可访问,而异步通知则意味着设备通知自身可访问,实现了异步I/O。由此可见,这几种方式I/O可以互为补充。
图9.1呈现了阻塞I/O,结合poll()的非阻塞I/O及异步通知在时间先后顺序上的不同。
图9.1 阻塞、非阻塞I/O、异步通知的区别
阻塞、非阻塞I/O、异步通知本身没有优劣,应根据不同的应用场景合理选择。
9.2 Linux异步通知编程
一、Linux信号
使用信号进行进程间通信(IPC)是UNIX系统中的一种传统机制,Linux系统也支持这种机制。在Linux系统中,异步通知使用信号来实现,Linux系统中可用的信号及其定义如表9-1所示。
表9-1 Linux信号
信号 | 值 | 含义 |
SIGHUP | 1 | 挂起 |
SIGINT | 2 | 终端中断 |
SIGQUIT | 3 | 终端退出 |
SIGILL | 4 | 无效命令 |
SIGTRAP | 5 | 跟踪陷阱 |
SIGIOT | 6 | IOT陷阱 |
SIGBUS | 7 | BUS错误 |
SIGFPE | 8 | 浮点异常 |
SIGKILL | 9 | 强行终止(不能被捕获或忽略) |
SIGUSR1 | 10 | 用户定义的信号1 |
SIGSEGV | 11 | 无效的内存段处理 |
SIGUSR2 | 12 | 用户定义的信号2 |
SIGPIPE | 13 | 办关闭管道发生写操作 |
SIGALRM | 14 | 计时器到期 |
SIGTERM | 15 | 终止 |
SIGSTKFLT | 16 | 堆栈错误 |
SIGCHLD | 17 | 子进程已经停止或退出 |
SIGCONT | 18 | 如果停止了,继续执行 |
SIGSTOP | 19 | 停止执行(不能被捕获或忽略) |
SIGTSTP | 20 | 终端停止信号 |
SIGTTIN | 21 | 后台进程需要从终端读取输入 |
SIGTTOU | 22 | 后台进程需要从终端写出 |
SIGURG | 23 | 紧急的套接字事件 |
SIGXCPU | 24 | 超额使用CPU分配的时间 |
SIGXFSZ | 25 | 文件尺寸超额 |
SIGVTALRM | 26 |