终端和操作系统

终端和操作系统

2025 南京大学《操作系统原理》
终端和操作系统

程序是怎么和终端 “配对” 的?

用户登录的起点

  • 系统启动 (内核 → init → getty)
  • 远程登录 (sshd → fork → openpty)
    • stdin, stdout, stderr 都会指向分配的终端
  • vscode (fork → openpty)

login 程序继承分配的终端

  • (是的,login 是一个程序)
  • fork() 会继承文件描述符 (指针)
    • 因此,子进程也会指向同一个终端
2025 南京大学《操作系统原理》
终端和操作系统

终于,我们有了足够的机制实现 “用户界面”

2025 南京大学《操作系统原理》
终端和操作系统

当然,不是图形的

UNIX Shell: “终端” 时代的经典设计

  • “Command-line interface” (CLI) 的巅峰

center

2025 南京大学《操作系统原理》
终端和操作系统

进程管理:要解决的问题

我们有那么大一棵进程树,都指向同一个终端,有的在前台,有的在后台,Ctrl-C 到底终止哪个进程?

答案:终端才不管呢

  • 它只管传输字符
    • Ctrl-C: End of Text (ETX), \x03
    • Ctrl-D: End of Transmission (EOT), \x04
    • stty -a: 你可以看到按键绑定 (奇怪的知识增加了)
  • 操作系统收到了这个字符
    • 就可以对 “当前” 的进程采取行动
2025 南京大学《操作系统原理》
终端和操作系统

终端上的 “当前进程”

作为操作系统的设计者,需要在收到 Ctrl-C 的时候找到一个 “当前进程”

你会怎么做?

  • fork() 会产生树状结构
    • (还有托孤行为)
  • Ctrl-C 应该终止所有前台的 “进程们”
    • 但不能误伤后台的 “进程们”
2025 南京大学《操作系统原理》
终端和操作系统

会话 (Session) 和进程组 (Process Group)

center

2025 南京大学《操作系统原理》
终端和操作系统

会话和进程组:机制

给进程引入一个额外编号 (Session ID,大分组)

  • 子进程会继承父进程的 Session ID
    • 一个 Session 关联一个控制终端 (controlling terminal)
    • Leader 退出时,全体进程收到 Hang Up (SIGHUP)

再引入另一个编号 (Process Group ID,小分组)

  • 只能有一个前台进程组
  • 操作系统收到 Ctrl-C,向前台进程组所有进程发送 SIGINT
    • (真累……但你也想不到更好的设计了)
2025 南京大学《操作系统原理》
终端和操作系统

会话和进程组:API

太不优雅了

  • setsid/getsid
    • setsid 会脱离 controlling terminal
  • setpgid/getpgid
  • tcsetpgrp/tcgetpgrp
    • 迷惑 API

以及……uid, effective uid (?), saved uid (???)

2025 南京大学《操作系统原理》
终端和操作系统

终于能实现 Job Control 了

窗口和多任务:终端可以有 “一个前台进程组”

  • “最小化” = Ctrl-Z (SIGTSTP)
    • SIGTSTP 默认行为暂停进程,收到 SIGCONT 后恢复
  • “切换” = fg/bg (tcsetpgrp)

为了实现 “窗口栏上的按钮”,还很是大费周章

  • 还不如 tmux 管理多个 pty 呢 (选择性 “绘制” 在终端上)
    • 那是因为发明 session/pg 的时候还没有 pty 呢……

center

2025 南京大学《操作系统原理》
终端和操作系统

是的,历史的糟粕

但是,这是 POSIX 的一部分……

  • 😂 几乎任何人都无法预知 “软件” 的未来

回头看这个问题

  • 我们不需要 “绑定进程到设备”
  • 管理程序 (tmux, gnome, ...) 去模拟就行
    • Window Manager: 只需要 “进程组” 就行了
      • 关窗口,全部 ❌ 一个不留
    • Android: 每个 app 都是不同的用户
      • 强行终止 = 杀掉属于这个用户的所有进程
    • Snap: 程序在隔离的沙箱运行
      • AppArmor + seccomp + namespaces (真狠)
2025 南京大学《操作系统原理》
终端和操作系统

在未来回头看现在

人机交互的方式根本不应该是这样的

  • 我们很少能清醒地认识到
    • 我要做 XX
    • 应该分解成 Y(Z,W)TY \to (Z, W) \to T
  • 因此,坐在电脑前的大部分时间都浪费了
2025 南京大学《操作系统原理》
终端和操作系统

最后:Ctrl-C 到底做了什么?

signal

  • 注册一个信号的 “处理程序” ff
    • 操作系统会记下这个 ff

kill

  • 在程序从操作系统返回时,强制加一个向 ff 的跳转
    • 程序 = 状态机
    • 只要 “模拟” 调用 ff 的行为即可

今天有更可靠的版本 (sigaction)

  • 让 AI 帮你解释吧
2025 南京大学《操作系统原理》