用户进程使用3个文件描述符与终端通信。终端被视为unix中的文件(例如/dev/tty
),并且还具有文件描述符,主要,次要编号,供内核识别。因此内核通过终端与用户进程通信。另一种沟通方式是通过我们都知道的系统调用。
假设用户进程正在等待输入(例如:enter two numbers: _ _
)。当我们在键盘上按 1 和 2 时,键盘缓冲区被填满,与键盘关联的设备驱动程序将识别它并将在其等待队列中唤醒进程。那么这些数据(即1
和2
)如何为用户进程提供支持?我猜是通过终端。
如果重定向输出会发生什么,例如$ ./a.out > file
?我已使用isatty()
检查过程与任何终端无关。那么内核将如何与用户进程交互?假设我的程序需要键盘的一些输入。
答案 0 :(得分:1)
当程序调用输入函数时,例如:
nread = read(FILENO_STDIN, buffer, sizeof(buffer));
a"系统调用"进入内核。这个内核例程确保传递给它的缓冲区在程序的地址空间中,然后将字符(不超过传入的大小)从终端设备的内核缓冲区复制到缓冲区中提供并返还给你的数量。
如果文件描述符(arg 1)指向打开的文件,则会发生非常类似的事情 - 数据来自文件系统的内核缓冲区(可能需要先从实际设备复制到那里) )。
答案 1 :(得分:0)
你问题的高级回答是你有
User process <> Kernel <> 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.