我一直在想scanf()/printf()在硬件和操作系统级别上是如何工作的。数据流向何处,操作系统在这些时候到底在做什么?操作系统做出了哪些调用?等等...
我一直在想scanf()/printf()在硬件和操作系统级别上是如何工作的。数据流向何处,操作系统在这些时候到底在做什么?操作系统做出了哪些调用?等等...
scanf() 和 printf() 是 C 标准库 libc 中的函数,分别调用 read() 和 write() 操作系统系统调用,并分别与文件描述符 stdin 和 stdout 通信 (fscanf 和 fprintf 允许您指定要从中读取/写入的文件流)。
对 read() 和 write() (以及所有系统调用) 的调用会导致 '上下文切换',从用户级应用程序切换到内核模式,这意味着它可以执行特权操作,如直接与硬件通信。根据应用程序的启动方式,'stdin' 和 'stdout' 文件描述符可能绑定到控制台设备 (如 tty0),或某种虚拟控制台设备 (如 xterm 提供的)。read() 和 write() 安全地复制数据到/从称为 'uio' 的内核缓冲区。
scanf 和 printf 的格式字符串转换部分不是在内核模式下发生,而只是在普通用户模式 (libc 内部) 中进行。关于系统调用的一般经验法则是尽可能少地切换到内核模式,既可以避免上下文切换的性能开销,还可以保证安全性(在内核模式下发生的任何事情都需要非常小心!内核模式中的代码越少,操作系统中的错误和安全漏洞就越少)。
顺便说一句..所有这些都是从 Unix 的角度写的,我不知道 MS Windows 如何工作。
scanf
和 printf
幸运地不会每次都调用 read
或 write
。它们(通常来说,我在简化)实际上维护一个缓冲区,并尽可能减少系统调用的次数以减少内核进出的切换。典型的 Windows libc 实现方式也非常类似,但使用了 ReadFile
和 WriteFile
系统调用。内核内部的详细细节不同,但基本的抽象和整体数据流非常相似。 - RBerteig在我的操作系统上,我正在使用基于函数getch()和putch()的scanf和printf。
在编程中,scanf、printf等函数不能直接用C/C++语言编写。实际上,它们都是通过使用关键字“asm”在汇编语言中编写的。任何使用关键字“asm”编写的内容都会直接引入目标文件,无论是否编译(即使编译后也不会改变)。在汇编语言中,我们有预定义的代码可以实现所有这些函数......因此,简而言之,SCANF PRINTF等所有函数都是在内部以汇编语言编写的。您可以使用关键字“ASM”设计自己的输入函数。