# 5.2 代码：控制台输出

在连接到控制台的文件描述符上执行`write`系统调用，最终将到达`uartputc`(***kernel/uart.c***:87) 。设备驱动程序维护一个输出缓冲区（`uart_tx_buf`），这样写进程就不必等待UART完成发送；相反，`uartputc`将每个字符附加到缓冲区，调用`uartstart`来启动设备传输（如果还未启动），然后返回。导致`uartputc`等待的唯一情况是缓冲区已满。

每当UART发送完一个字节，它就会产生一个中断。`uartintr`调用`uartstart`，检查设备是否真的完成了发送，并将下一个缓冲的输出字符交给设备。因此，如果一个进程向控制台写入多个字节，通常第一个字节将由`uartputc`调用`uartstart`发送，而剩余的缓冲字节将由`uartintr`调用`uartstart`发送，直到传输完成中断到来。

需要注意，这里的一般模式是通过**缓冲区**和**中断机制**将设备活动与进程活动解耦。即使没有进程等待读取输入，控制台驱动程序仍然可以处理输入，而后续的读取将看到这些输入。类似地，进程无需等待设备就可以发送输出。这种解耦可以通过允许进程与设备I/O并发执行来提高性能，当设备很慢（如UART）或需要立即关注（如回声型字符(echoing typed characters)）时，这种解耦尤为重要。这种想法有时被称为I/O并发

