第165页 | 现代操作系统 | 阅读 ‧ 电子书库

同步阅读进度,多语言翻译,过滤屏幕蓝光,评论分享,更多完整功能,更好读书体验,试试 阅读 ‧ 电子书库

5.2.2 程序控制I/O

I/O可以以三种根本不同的方式实现。在本小节中我们将介绍第一种(程序控制I/O),在后面两小节中我们将研究另外两种(中断驱动I/O和使用DMA的I/O)。I/O的最简单形式是让CPU做全部工作,这一方法称为程序控制I/O(programmed I/O)。

借助于例子来说明程序控制I/O是最简单的。考虑一个用户进程,该进程想在打印机上打印8个字符的字符串“ABCDEFGH”。它首先要在用户空间的一个缓冲区中组装字符串,如图5-7a所示。

然后,用户进程通过发出系统调用打开打印机来获得打印机以便进行写操作。如果打印机当前被另一个进程占用,该系统调用将失败并返回一个错误代码,或者将阻塞直到打印机可用,具体情况取决于操作系统和调用参数。一旦拥有打印机,用户进程就发出一个系统调用通知操作系统在打印机上打印字符串。

然后,操作系统(通常)将字符串缓冲区复制到内核空间中的一个数组(如p)中,在这里访问更加容易(因为内核可能必须修改内存映射才能到达用户空间)。然后操作系统要查看打印机当前是否可用。如果不可用,就要等待直到它可用。一旦打印机可用,操作系统就复制第一个字符到打印机的数据寄存器中,在这个例子中使用了内存映射I/O。这一操作将激活打印机。字符也许还不会出现在打印机上,因为某些打印机在打印任何东西之前要先缓冲一行或一页。然而,在图5-7b中,我们看到第一个字符已经打印出来,并且系统已经将“B”标记为下一个待打印的字符。

图 5-7 打印一个字符串的步骤

一旦将第一个字符复制到打印机,操作系统就要查看打印机是否就绪准备接收另一个字符。一般而言,打印机都有第二个寄存器,用于表明其状态。将字符写到数据寄存器的操作将导致状态变为非就绪。当打印机控制器处理完当前字符时,它就通过在其状态寄存器中设置某一位或者将某个值放到状态寄存器中来表示其可用性。

这时,操作系统将等待打印机状态再次变为就绪。打印机就绪事件发生时,操作系统就打印下一个字符,如图5-7c所示。这一循环继续进行,直到整个字符串打印完。然后,控制返回到用户进程。

操作系统相继采取的操作总结在图5-8中。首先,数据被复制到内核空间。然后,操作系统进入一个密闭的循环,一次输出一个字符。在该图中,清楚地说明了程序控制I/O的最根本的方面,这就是输出一个字符之后,CPU要不断地查询设备以了解它是否就绪准备接收另一个字符。这一行为经常称为轮询(polling)或忙等待(busy waiting)。

图 5-8 使用程序控制I/O将一个字符串写到打印机

程序控制I/O十分简单但是有缺点,即直到全部I/O完成之前要占用CPU的全部时间。如果“打印”一个字符的时间非常短(因为打印机所做的全部事情就是将新的字符复制到一个内部缓冲区中),那么忙等待还是不错的。此外,在嵌入式系统中,CPU没有其他事情要做,忙等待也是合理的。然而,在更加复杂的系统中,CPU有其他工作要做,忙等待将是低效的,需要更好的I/O方法。

请支持我们,让我们可以支付服务器费用。
使用微信支付打赏


上一页 · 目录下一页


下载 · 书页 · 阅读 ‧ 电子书库