# Ctrl-C

Ctrl-C 我们再熟悉不过了,可如果一开始,我们有 Ctrl-C 这样一个具体的需求,操作系统应该怎样设计 / 实现?

  • UNIX 信号
  • job control 怎样在 shell 里管理多个进程

为什么 Ctrl-C 能退出程序?
1. Ctrl-C 并不能杀掉所有的程序,比如没法用 Ctrl-C 来退出 vim
2. 两个进程同时使用了 read(STDIN_FILENO,buf,size); ,按下 Ctrl-C ,谁收到了?

Ctrl-C 的背后涉及若干操作系统中的对象
按下 Ctrl-C 的终端

  • tty(1)
  • echo hello > $(tty) 我们甚至可以向其它 tty 打印

事实上,它俩都不是最先收到 Ctrl-C 的,终端最先收到 Ctrl-C ,向前台的进程组 (process group) 发送了 SIGINT 信号,这是一种进程间通信的机制,和 (管道) pipe 和 (共享内存) mmap 一样,只不过信号是异步的,而管道和共享内存是同步的,在按下 Ctrl-C 时,同时给进程发送了信号 signal ,进程就会跳转到处理器预设的 signal 处理程序,等于说在软件上模拟硬件上的中断机制,使得可以在进程间做异步通信。

# signal 函数

//signal 函数原型
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int sinum,sighandler_t handler);

对于 sighandler_t signal(int signum, sighandler_t handler) 函数来说, signum 显然是信号的编号, handler 是中断函数的指针。 typedef void (*sighandler_t)(int) 中断函数的原型中,有一个参数是 int 类型,显然也是信号产生的类型,方便使用一个函数来处理多个信号。

signal() 会按照参数 signum 指定的编号来设置该信号的处理函数,当指定的信号到达时就会跳转到参数 handler 指定的函数执行,如果参数 handler 不是指针,则必须是下列两个常数之一:

  • SIG_IGN 忽略参数 signum 指定的信号
  • SIG_DFL 将参数 signum 指定的信号重设为预设的信号处理方式
    返回先前的信号处理函数指针,如果有错误则返回 SIG_ERR(-1)

当使用 vim 编辑时,之所以 Ctrl-C 无效,因为它的进程不响应这个机制;在手册里,有这样说, signal() 可以设置一个编号为 signum 信号的 handler ,可以有 SIG_IGN (忽略这个信号)、 SIG_DFL (默认的信号处理程序),对于 Ctrl-C 来说, SIG_DFL 的处理就是退出程序;而 vim 设定了一个自定义的 signal handler

# job control

何为 PID ?进程标识符,为每个进程分配唯一标号,进程创建时分配 PIDShell 支持前台进程组和后台进程组,进程组指的是已从 shell 命令行启动的命令;通常,前台进程组可以控制终端;一个程序也可以附上 & 被后台运行,比如 testrun 是一个程序, testrun &[2] 4365 成为一个后台进程组;如果后台启动了多个进程组, shell 将按照这些进程组启动的顺序进行编号,比如

$ testrun &[2] 4365
$ backup &[3] 4374
$ account &[4] 4377

当后台进程组完成了会报 [1] + done testrun ,jobs 命令将会列出所有的后台进程组, jobs -l 选项还可以列出 PID ,比如

[2]  Running testrun & 
[3]- Running backup &
[4]+ Running account &

另外, fg(foreground) 命令可以在前台恢复执行被挂起的进程,默认情况下, fg 和下面的 bg 针对于最近的进程,如果有编号,比如 fg %2 ,表示使第 2 个任务在前台运行;或者可以使用 fg %testrun 命令, %+ 针对于最近的后台进程组,而 %- 针对于次新的后台进程组。 Ctrl-Z 可以用来挂起一个进程放入后台, bg 命令可以在后台恢复执行被挂起的进程,而此时将无法再使用 Ctrl-Z 再次挂起该进程。比如,正在使用 vi 编辑一个文件,需要执行 shell 命令查询一些需要的信息,可以使用 Ctrl-Z 挂起 vi ,等执行完 shell 命令之后再使用 fg 恢复 vi 继续编辑你的文件。

更新於 閱讀次數

請我喝[茶]~( ̄▽ ̄)~*

fygod 微信支付

微信支付

fygod 支付寶

支付寶

fygod PayPal

PayPal