55·进程管理进阶

后台前台与作业控制

bgfgjobs

第55课:后台前台与作业控制

学习目标

  1. 理解前台、后台进程的概念及其在终端中的作用
  2. 掌握使用 jobsfgbg 命令查看和管理作业
  3. 学会使用 Ctrl+ZCtrl+C 等快捷键控制进程
  4. 理解并处理后台进程与终端控制(TTY)的关系

核心概念

1. 前台与后台进程

  • 前台进程:当前在终端窗口中运行,接收用户输入(如键盘按键)并直接影响终端显示的进程。一个终端会话通常同一时间只有一个前台进程。
  • 后台进程:在后台运行,不占用终端的输入和输出。用户可以在执行后台命令的同时继续使用终端。
    • 比喻:把终端窗口想象成一个舞台。前台进程是正在舞台上表演的演员(聚光灯下),而后台进程则是在后台准备、但不在舞台上的演员。

2. 作业(Job)与作业控制

  • 当你在Shell(如bash)中启动一个进程时,Shell会为其分配一个作业号(Job ID)。这是Shell内部管理的标识。
  • 作业控制(Job Control)允许你:
    • 暂停正在运行的进程
    • 在前台和后台之间切换进程
    • 查看当前有哪些进程在后台或已暂停

3. 常用控制信号与快捷键

  • Ctrl+C:向当前前台进程发送 SIGINT 信号,通常用于终止进程。
  • Ctrl+Z:向当前前台进程发送 SIGTSTP 信号,将其挂起(暂停)。进程状态变为 Stopped
  • 命令行末尾加 &:将命令直接放入后台运行。例如 sleep 60 &

代码示例

# 场景:演示作业控制的典型工作流程

# 1. 启动一个前台任务,并立即挂起它
sleep 300
# 按下 Ctrl+Z
# 终端会显示:[1]+ Stopped sleep 300
# 说明:作业号[1]的 `sleep 300` 进程已被挂起。

# 2. 查看当前的所有作业
jobs
# 输出示例:
# [1]+ Stopped                 sleep 300
# [2]- Running                 find / -name “*.log” &
# (+ 表示默认作业,- 表示上一个作业)

# 3. 将挂起的作业放到后台继续运行
bg %1 # 或简写为 bg %1, %1 是作业号
# 输出:[1]+ sleep 300 &
# 说明:作业[1]现在已在后台运行。

# 4. 再次查看作业状态,确认它已在后台运行
jobs
# [1]+ Running                 sleep 300 &

# 5. 将后台作业调回前台运行
fg %1
# 说明:sleep 300 又回到前台。你可以再次用 Ctrl+Z 挂起,或用 Ctrl+C 终止。

# 6. 终止一个后台作业
# 首先,用 jobs 找到作业号,例如作业号为 2 的 find 命令
kill %2 # 通过作业号发送 SIGTERM 信号终止
# 你也可以先将作业调回前台 (fg %2),然后用 Ctrl+C 终止。

# 7. 直接启动一个后台任务
ping -c 100 localhost &
# 输出:[3] 12345 (显示作业号[3]和进程ID PID)
jobs
# [3]+ Running                 ping -c 100 localhost &

实践练习

练习 1:基本的前后台切换

  1. 启动一个执行 top 命令的前台进程。
  2. 不要退出 top,将其挂起。
  3. 使用 jobs 命令确认它已停止。
  4. 将其放到后台运行。
  5. 将其再次调回前台,并正常退出 top

预期输出(思路)

# 输入 top
# ... top 运行界面 ...
# 按 Ctrl+Z
# 输出: [1]+ Stopped                 top
$ jobs
# [1]+ Stopped                 top
$ bg %1
# [1]+ top &
$ jobs
# [1]+ Running                 top &
$ fg %1
# top 回到前台
# 在 top 界面按 q 退出

练习 2:管理多个后台作业

  1. 在后台启动两个长时间命令:sleep 200 &sleep 300 &
  2. 使用 jobs 命令查看它们。
  3. 将第二个 sleep(作业号大的那个)调回前台。
  4. 按下 Ctrl+Z 挂起它,然后放回后台。
  5. 使用 kill 命令终止这两个后台 sleep 进程。

预期输出(关键步骤)

$ sleep 200 &
[1] 11111
$ sleep 300 &
[2] 22222
$ jobs
[1]-  Running                 sleep 200 &
[2]+  Running                 sleep 300 &
$ fg %2
# sleep 300 在前台运行
# 按 Ctrl+Z
[2]+  Stopped                 sleep 300
$ bg %2
[2]+ sleep 300 &
$ kill %1 %2
[1]-  Terminated              sleep 200
[2]+  Terminated              sleep 300

练习 3:理解信号与进程状态

  1. 启动一个后台 sleep 600 进程。
  2. 不要使用作业号,直接用 pspgrep 找到它的PID。
  3. 使用 kill -STOP <PID> 挂起它。
  4. 使用 jobs 命令观察它的状态。
  5. 使用 kill -CONT <PID> 恢复它。
  6. 使用 kill <PID> 终止它。

预期输出(关键步骤)

$ sleep 600 &
[1] 33333
$ pgrep sleep
33333
$ kill -STOP 33333
$ jobs
[1]+  Stopped                 sleep 600
$ kill -CONT 33333
$ jobs
[1]+  Running                 sleep 600 &
$ kill 33333
[1]+  Terminated              sleep 600

常见错误

  1. 试图用 bg 启动新命令bgfg 只作用于已经被挂起或已在后台的作业。不能用 bg sleep 10 来启动后台任务,正确的做法是 sleep 10 &
  2. 混淆作业号(Job ID)和进程号(PID)jobsfgbgkill %n 使用的是Shell分配的作业号(如 %1)。而系统级的 pskill(不带%)使用的是进程PID。不要混用,例如 fg 1234 是错误的,应该是 fg %1
  3. 认为后台进程在退出终端后继续运行:这是下一课 nohupdisown 解决的问题。默认情况下,当你关闭终端(或断开SSH连接),终端会向其下的所有进程(包括后台进程)发送 SIGHUP 信号,导致它们终止。
  4. 不清楚 Ctrl+ZCtrl+C 的区别Ctrl+Z暂停(挂起),进程仍在内存中;Ctrl+C终止。误按 Ctrl+Z 后,如果不处理,进程就静静地停在那里。
  5. jobs 命令在子Shell中无效jobs 是Shell内置命令,只显示当前Shell会话启动的作业。如果你在脚本里或另一个终端里运行 jobs,看不到其他终端的作业。

小结

  • 前后台是进程与终端交互的两种模式。前台独占终端,后台则不然。
  • 使用 命令 & 将任务放入后台运行。
  • 使用 Ctrl+Z 挂起前台进程,Ctrl+C 终止。
  • 作业控制三剑客
    • jobs:查看当前Shell会话的作业列表及其状态。
    • bg %n:将作业号为 n 的已停止作业放到后台继续运行。
    • fg %n:将作业号为 n 的后台或已停止作业调回前台运行。
  • 后台进程与启动它的终端(控制终端)紧密关联。终端关闭会导致后台进程收到 SIGHUP 信号而退出。这是理解 nohupscreen/tmux 的基础。
  • 信号(如 SIGTSTP, SIGCONT, SIGTERM)是控制进程状态的核心机制,Ctrl+Zbgfgkill 命令本质上都在发送特定信号。

练习编辑器

rust
Loading...

继续学习

完成本课后,建议继续学习下一课「nohup、screen 与 tmux」 以巩固所学知识。