linux进程组、会话以及任务管理

进程组

当我们在终端中敲下一条命令,然后按下回车的时候,Shell会开启一个新进程来执行这条命令。如果这条命令是由管道连接起来的多个命令组成的话,Shell便会开启多个进程来执行这一组任务。无论是单独的一条命令,还是由管道连接的多条命令,都会被放入到一个新的进程组(任务)中。只包含一条命令的时候,就会创建一个由一个进程组成的进程组。进程组中的每个进程都具有相同的进程组标识符(进程组ID),这个进程组标识符其实就是进程组中某个进程(即进程组组长)的进程ID。

会话

会话指的是一组进程组(任务)。一个会话中的所有进程都具有相同的会话标识符,会话首进程是指创建会话的进程,其进程ID会成为会话ID。使用会话最多的是支持任务控制的shell,由shell创建的所有进程组及shell自身隶属与同一个会话,shell自身就是该会话的会话首进程。

在任意时刻,会话中总有一个前台进程组(前台任务),可以从终端读取输入,向终端发送输出。如果用户输入Ctrl+C或者Ctrl+Z,就可以分别让任务终止或挂起。同时,一个会话还可以拥有任意多个后台进程组,后台进程组可以用’&’结尾的命令行创建。

任务控制

支持任务控制的shell提供了创建后台任务、列出所有任务、向任务发送信号,以及在前后台任务之间来回切换等命令。

shell中的任务分为三种状态Running、Stopped、Done。

1
<command> &

在一个命令后添加 & 即可简单的放入后台运行。通过 & 放置到后台的命令,仍保持 Running 状态,默认的标准输出和标准错误输出仍为终端,也就是说你仍然会看到它打印出的信息,这应该通过重定向来解决。如果输出的内容不需要,可以简单的重定向到 /dev/null。

当与终端断开连接时(即关闭终端),任务会收到 SIGHUP 信号而被杀死,如果需要持续运行,则需使用 nohup 命令将其放置到系统后台,而非当前终端的后台,如:

1
$ nohup python3 local.py 2>&1 &

这将放入系统后台运行python3 local.py,并将 stderr 重定向到 stdout。这是我们在终端中输入exit来退出终端,该任务就不会被杀死。

1
CTRL+Z

这将暂停当前任务,成为 Stopped 状态,并放入任务列表。

1
jobs

显示所有当前任务,如:

1
2
3
$ jobs
[1]+ Stopped vim
[2]- Running python3 local.py 2>&1 &
1
fg

通过fg [%n]来激活任务到前台,如果省略%n参数,则默认激活标记为+的任务,且标记为-的任务将被标记为+

1
bg

通过bg [%n]来运行Stopped状态的后台任务,任务将继续运行,状态变为Running,且命令后增添了 & 字样。

当你忘记将任务放入后台运行,即可组合使用 CTRL+Z 和 bg 来弥补它。

1
kill

通过 kill –signal %n 来快捷地杀死后台任务。

signal 常见的有:

1
2
3
4
5
6
7
1 SIGHUP 终端断开连接
2 SIGINT 中断(CTRL+C)
3 SIGQUIT 退出(CTRL+\\)
9 SIGKILL 强行终止
15 SIGTERM 终止
18 SIGCONT 继续(fg、bg)
19 SIGSTOP 暂停(CTRL+Z)