OS 如何知道向哪个进程发送键盘中断?

How does OS know to which process send a keyboard interrupt?

下面是一个简单的 c 程序(适用于 Ubuntu OS),它等待任何键盘键被按下然后终止。

#include <cstdio>
#include <conio.h>

int main() {
    while(true) {
        if (_kbhit()) {
            printf("Key hit\n");
            return 0;
        }
    }
    return 0;
}

如果我在终端 nr 上启动这个程序。 1,仅当鼠标指向终端 1 时,程序才会对我按下按键做出反应。因此,如果两个这样的程序同时 运行 作为单独的进程,按下一个键将最多终止一个程序.

OS如何知道向哪个进程发送键盘中断?

首先,这是一个直接从键盘缓冲区读取输入的程序(a.k.a。键盘记录器):

#include <stdio.h>
#include <linux/input.h>

int main() {
    // Note: on other computers path to a keyboard buffer might differ
    const char path[] = "/dev/input/by-path/platform-i8042-serio-0-event-kbd";
    FILE* keyboard_buffer = fopen(path, "r");
    if (keyboard_buffer == NULL) {
        printf("Failed to open. Try running with root access.\n");
        return 1;
    }

    struct input_event event;
    while(1) {
        fread(&event, sizeof event, 1, keyboard_buffer);
        if (event.type == EV_KEY && event.value == 1) {
            printf("Key %d has been pressed\n", event.code);
            fclose(keyboard_buffer);
            return 0;
        }
    }
}

如果你启动这个程序并在任何地方按下键,它会立即退出,因为这里我们不是从标准输入读取键盘数据,而是从安装在文件上的键盘缓冲区读取键盘数据/dev/input/by-path/platform-i8042-serio-0-event-kbd

另一方面,您的代码使用 conio.h 库读取键盘事件,它在内部调用 getchar()stdin:

读取

When a command is executed via an interactive shell, the streams (i.e. stdin) are typically connected to the text terminal on which the shell is running,

一个进程的标准输入将指向与另一个进程的标准输入不同的文件。

现在 OS(即键盘驱动程序)所做的是将按键从键盘缓冲区转发到前台进程的标准输入。由于在您的情况下,只有一个程序 运行 作为前台进程,因此 key-press 将仅转发到标准输入流之一。

大问题。在您的示例中,正如 所述,它 没有;取决于您对 OS.

的定义

在经典的unix系统中,GUI是由用户space中相对常规的程序运行提供的。 GUI(例如 X11)是唯一连接到实际键盘设备的;并将这些键转换为 GUI 中的 events。按下某个键时,GUI 中具有 输入焦点 的 window 将接收事件。

终端仿真器 是一个在 GUI 中运行的程序,为程序提供 1970 年代的 GUI 界面。该程序使用一种特殊类型的 tty-device,称为 pseudo-tty,其功能非常类似于支持终端特定功能的 pipe(2) (tc* , 读写控制)。当 终端仿真器 接收到指示击键的 GUI 事件时,它会将其注入 pseudo-tty,然后将其作为 ascii/utf-8 字符提供给程序。

GUI 通过配置选择哪个 window 具有输入事件的焦点。有些人更喜欢地理 - window 鼠标指针所在的位置接收这些事件;有些人更喜欢 单击以聚焦,您必须在其中单击 window 以确定谁获得焦点。两者各有优缺点;但是如果你经常在 irc/slack/... 中收到来自某人的奇怪消息,他们可能会选择 click-to-focus.

在没有图形用户界面的情况下,答案既简单又复杂。在明显的情况下,它是程序向您打印“$”提示符;在复杂的情况下,您需要阅读 会话、进程组、控制终端、作业控制