用户进程,terminal和内核之间的通信

用户进程使用3个文件描述符与terminal进行通信。 terminal被认为是unix中的文件(例如/dev/tty ),并且还有内核的文件描述符,主要,次要编号来标识它。 所以内核通过terminal与用户进程通信。 另一种沟通方式是通过我们都知道的系统调用。

假设用户进程正在等待input(例如: enter two numbers: _ _ )。 当我们在键盘上按下12时,键盘缓冲区被填满,与键盘相关联的设备驱动程序将识别它并将在其等待队列中唤醒进程。 那么这个数据(即12 )如何对用户进程有效? 这将是通过terminal我猜。

另外如果redirect输出,例如$ ./a.out > file什么? 我已经检查使用isatty()该进程是不是与任何terminal关联。 那么内核将如何与用户进程交互? 假设我的程序需要键盘input。

当你的程序调用一个输入函数时,例如:

 nread = read(FILENO_STDIN, buffer, sizeof(buffer)); 

一个“系统调用”被编入内核。 这个内核例程确保你传递给它的缓冲区在你的程序的地址空间中,然后从终端设备的内核缓冲区拷贝字符(不超过你传入的大小)到你提供的缓冲区并返回给你那些。

如果文件描述符(arg 1)指向一个打开的文件 – 数据来自文件系统的内核缓冲区(可能需要先从实际设备复制到那里),则会发生类似的情况。

你的问题的高层答案是,你有

 User process <> coreel <> Terminal Driver 

在一些系统中,终端驱动程序可能是内核的一部分。 在其他情况下,它是在内核模式下执行的独立代码(很好的区分)。

当某人按下某个键时,会触发由驱动程序处理的系统中断。 在这里,可能会发生以下两种情况之一,这取决于内核如何告诉驱动程序行为或驱动程序是如何实现的。

1)驾驶员可以简单地将按键存储在缓冲区中; 或者2)驱动程序每次获得按键时都可以通知内核。

内核可能以多种方式与进程交互,具体取决于系统以及进程如何配置终端:

1)内核可能对终端的数据不做任何处理,直到进程调用它为止。 该进程提供一个缓冲区,内核从其内部缓冲区(或驱动程序的缓冲区)复制数据。 2)内核可能会向进程发送软件中断(例如,Windows或VMS)。 在这种情况下,该进程将预先向内核提供一个缓冲区来将数据复制到内核。 3)内核可以将一个事件排队到进程将不得不查询的进程。

关于您的部分问题,重定向完全在内核之外进行管理。 一个应用程序(通常是一个命令行shell)通常会解释这个

  ./a.out > file 

通过

 1) Open FILE. 2) Create a new process where the standard output is the handle to FILE. 3) Run a.out in that process.