【问题标题】:Communication between user process, terminal and kernel用户进程、终端和内核之间的通信
【发布时间】:2014-11-06 22:11:46
【问题描述】:

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

假设用户进程正在等待输入(例如:enter two numbers: _ _)。当我们在键盘上按下 12 时,键盘缓冲区被填满,与键盘关联的设备驱动程序将识别它并唤醒等待队列中的进程。那么这些数据(即12)是如何提供给用户进程的呢?我猜它会通过终端。

如果重定向输出会发生什么,例如$ ./a.out > file?我已使用isatty() 检查该进程未与任何终端关联。那么内核将如何与用户进程交互呢?假设我的程序需要一些键盘输入。

【问题讨论】:

  • 终端本身被内核特殊处理。有进程组,组的前台进程获取控制台输入。您可以使用screen 之类的东西将多个程序置于前台。除了终端的性质之外,我看不出你的问题是什么没有很多重复?

标签: linux process terminal kernel


【解决方案1】:

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

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

一个“系统调用”进入内核。此内核例程确保您传递给它的缓冲区位于程序的地址空间中,然后将字符(不超过您传入的大小)从终端设备的内核缓冲区复制到您提供的缓冲区中,并将计数返回给您那些。

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

【讨论】:

  • 我的用户进程中没有使用任何读取功能。我想知道键盘缓冲区中的数据是如何通过终端进入用户进程的。我在我的程序中使用 scanf。我在某处看到 scanf 反过来调用读取函数。那么 read 函数的参数如何与 scanf 映射。缓冲区地址可以是变量的地址(即&x),但是读取函数中的大小参数呢?如何计算。
  • 如果内核将键盘缓冲区数据直接复制到用户空间,那么数据是如何出现在终端上的。例如:输入两个整数:_ _ 。当我输入时,它不应该出现在终端上,而是应该直接复制到变量地址(在用户空间中)。我想知道数据如何在终端上显示以及如何复制到用户空间变量地址。请不要忽略终端部分。我想知道机制。谢谢
  • @debendranathtiwary scanf() 不会在内部调用 read() 函数。
  • @debendranathtiwary 如果您在某处调用scanf(),则调用read() 函数将数据从内核的终端缓冲区传输到用户空间缓冲区。 stdio 输入函数是缓冲的,因此当缓冲区为空时,典型的策略是发出一个读取缓冲区的完整大小,然后只需从缓冲区中复制一个或多个字符即可满足未来的“读取”,然后调整缓冲区中可用的字节数。常量BUFSIZ 给出了这个缓冲区的标称大小。
  • @JohnHascall 谢谢。好的,输入、输出和输出流是否只有 1 个缓冲区。据我所知,输出流与任何缓冲区无关。如果我错了,请纠正我。另外,我怎样才能直接访问这些缓冲区。
【解决方案2】:

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

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.

【讨论】:

  • 谢谢。 ./a.out > 文件不与终端关联(因为 isatty 失败)但是 ./a.out
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-30
  • 2011-06-23
  • 1970-01-01
  • 2018-02-10
  • 1970-01-01
  • 1970-01-01
  • 2012-07-15
相关资源
最近更新 更多