天天看点

write系统调用的实现 (你想知道的C语言 1.3)

Q: 承接printf的底层实现,write系统调用是否就是写到stdout文件最后传递给LCD驱动显示?

A: write系统调用确实会把数据写到kernel stdout buffer, 但不会直接传递给LCD驱动显示.

    这也是write系统调用和很多驱动实现不同的地方,很多驱动是会直接丢给对应的硬件处理完成

  必要的任务, GUI操作系统对于write系统调用的处理却很保守,这种保守并没有错. 对于内核来说,

  它并不知道数据真正要在哪个GUI应用程序中输出,所以,内核只会接收数据,然后唤醒"read线程",

  并让"read线程"拿到write的数据,然后返回给用户GUI应用程序调用GUI API输出数据.

    所以,不要小看了printf, 它没有字面意义的那么简单.

Q: 为什么在单用户模式或者DOS系统, 根本没有上面的描述这么复杂?

A: 单用户模式或者DOS系统,printf -> write -> show on screen 是一气呵成的, 在这种模式下,并没

有所谓的多GUI显示问题,所以write内部就是调用BIOS调用或者LCD驱动显示数据.

Q: printf -> write -> 唤醒"read线程" 到底是如何工作的?

A:    一般的操作系统都提供TTY框架,它提供了stdout/stdin的标准处理流程. 一种简单的理解是,

每个进程都会打开自己的stdout/stdin, 注意,stdout/stdin对应内核内部会有tty结构体对应, 最开始

运行的终端会不断用重定向的方式让子进程stdout/stdin最终指向自己. 终端就是展示数据的作用,

实际数据都存在各进程的内核tty结构中. 对于如何唤醒"read线程", 终端会监测子进程的stdout/stdin

的数据, 有输入就会按照指定方式显示,当然默认是原码展示. 内核会在stdout/stdin有数据时及时唤醒

终端"监测线程", 及时反馈给终端做展示.

   例如, Mac平台iTerm2应用程序,是模拟终端的GUI应用程序,如下是输入普通ascii字符输入的流程.

write系统调用的实现 (你想知道的C语言 1.3)
write系统调用的实现 (你想知道的C语言 1.3)
write系统调用的实现 (你想知道的C语言 1.3)
作者:     陈曦
环境:     MacOS 10.14.5
         Apple LLVM version 10.0.1 (clang-1001.0.46.4)
         Target: x86_64-apple-darwin18.6.0
 
转载请注明出处