如何在Linux中预置后台进程
1. 概述
众所周知,执行中的程序通常会接受输入,对其进行处理,并为我们提供适当的输出。Linux 作为一个多任务操作系统,支持许多进程(基本上是程序或命令)作为后台和前台作业的执行。
在本教程中,我们将讨论交互式流程和非交互式流程。此外,我们将了解Linux 中的作业控制 是什么。我们还将讨论从命令行执行多任务的基本方法——这在运行时间密集型程序时是必需的。
2.交互和工作控制
终端会话初始化和控制交互过程。换句话说,必须有人连接到系统才能启动这些进程;它们不会自动启动。这些进程可以在前台运行,从而占用启动程序的终端。只要此进程在前台运行,我们就无法启动其他应用程序。
**或者,它们可以在后台运行,以便我们启动程序的终端可以在程序运行时接受新命令。这种类型的进程被称为非交互式进程。**当一个进程在后台运行时,用户可以在终端中做其他事情。
Shell 提供了一种称为作业控制的功能,可以轻松处理多个进程。这种机制在后台和前台作业之间切换进程。使用这个系统,程序也可以立即在后台启动。
**作业控制是在前台和后台之间移动进程或命令以及暂停和恢复其执行的能力。**为了实现这一点,bash 引入了作业的概念,它本质上是一个或多个进程执行的命令。
Shell 在其作业控制实现中使用了一些简单的数据结构。有一个结构来表示一个子进程,包括它的进程 ID、它的状态和它返回的状态。
3. 后台和前台工作
**连接到终端的进程称为前台作业。**工作被称为在前台,因为它可以通过屏幕和键盘与用户交流。
**另一方面,与终端断开连接且无法与用户通信的进程称为后台作业。**如果后台作业需要与用户交互,它将停止并等待,直到建立与终端的连接。
我们可以将运行时不需要用户交互的作业(例如对大文件进行排序)放置在后台。这允许用户访问终端并继续工作,而不是等待很长的工作完成:
3.1. 在后台开始工作
我们可以使用jobs 命令列出 当前 shell 调用的所有作业。shell 列出每个作业的作业 ID,以及状态(正在运行、已停止或其他)以及启动作业的命令。shell 将最近的作业视为当前作业,并用加号标记。
与作业控制相关的命令将应用于当前作业。标有减号的所有其他工作都是以前的工作。可以使用百分号通过作业 ID 引用作业。因此,作业 1 称为 %1,作业 2 称为 %2,依此类推。
要将作业置于后台,我们可以简单地在 shell 命令的末尾添加与字符 (&)。
要对名为“foo”的文件进行排序,并将结果放入名为“bar”的文件中,我们可以发出以下命令:
$ sort < foo > bar &
3.2. 暂停前台作业
**我们(通常)可以通过键入 Ctrl-Z 来告诉 Linux 暂停当前连接到终端的作业。**shell 会通知我们该进程已被挂起,它会为挂起的作业分配一个作业 ID。
暂停的作业和在后台运行的作业之间存在很大差异。当暂停的作业停止时,该作业在前台或后台运行之前不会进行任何处理。
3.3. 将前台作业置于后台
如果我们在前台启动一项工作并希望将其置于后台,首先要做的是使用 Ctrl-Z 暂停该工作,这会释放终端:
$ tail -f temp.log
^Z[1]+ Stopped tail -f temp.log
然后,我们可以发出命令bg 将暂停的作业置于后台:
$ bg
[1] tail -f temp.log
$ jobs
[1]+ Running tail -f temp.log
bg命令可以接受作业 ID 作为参数。如果没有给出作业 ID,则bg假定我们指的是当前(暂停)作业。
3.4. 将后台作业带到前台
我们可以使用 Linux 命令fg 将后台作业重新连接到终端。
fg命令将接受作业 ID 作为参数。确保包括百分号:
$ fg %2
此命令会将作业 2 带到前台。如果没有给出作业 ID,fg将假定我们指的是当前(暂停)作业。
3.5. 开始暂停的工作
如果我们有一个暂停的作业要恢复运行,我们必须首先决定是希望它在前台运行还是在后台运行。一旦我们使用jobs命令找到了暂停作业的作业 ID,我们就可以使用bg(在后台运行作业)或fg(在前台运行作业)。
4. 信号
信号是发送到正在运行的程序以触发特定行为(例如退出或错误处理)的标准化消息。信号的常见用途是暂停、终止或终止进程。
我们可以使用 Ctrl-Z 暂停后台进程的执行,它发送信号SIGTSTP:
$ tail -f temp.log
^Z[1]+ Stopped tail -f temp.log
$ jobs
[1]+ Stopped tail -f temp.log
我们可以通过将后台进程发送到前台来终止它,然后使用 Ctrl-C 终止它,它发送信号SIGINT。
当然,我们可以使用这些 Linux 控件来停止或终止进程的执行。但是,终止后台进程的更直接的方法是使用kill 命令。它不使用作业 ID,而是使用 PID。kill -9 PID命令将使用相应的 PID 终止进程:
$ jobs
[1]+ Running tail -f temp.log
$ kill -9 97
[1]+ Killed tail -f temp.log
默认情况下,kill命令发送终止信号SIGKILL,即立即终止。
*与 Ctrl-Z 类似,我们也可以使用kill发送停止信号*SIGSTOP,这是一个进程挂起信号:
$ jobs
[1]+ Running tail -f temp.log
$ kill -19 152
[1]+ Stopped (signal) tail -f temp.log
$ jobs
[1]+ Stopped (signal) tail -f temp.log