首页 > 数据库 > 数据库开发技术 > 运维必会知识之Linux进程关系
进程process是指正在执行的程序;是程序正在运行的一个实例。它由程序指令,和从文件、其它程序中读取的数据或系统用户的输入组成
前台进程(也称为交互式进程) - 这些进程由终端会话初始化和控制。换句话说,需要有一个连接到系统中的用户来启动这样的进程;它们不是作为系统功能/服务的一部分自动启动。
后台进程(也称为非交互式/自动进程) - 这些进程没有连接到终端;它们不需要任何用户输入。
这指的是系统中的守护进程(daemon processes)。守护进程是一种在系统启动时启动并一直运行的特殊类型的后台进程。它们通常不受用户直接控制,而是由系统的 init 进程或其他管理工具启动和监控。
这些守护进程是为了执行特定的系统任务或提供某些服务,例如网络服务、日志记录等。它们通常以无交互的方式在后台运行,不会与用户的终端交互。
init 进程是 Linux 和类 Unix 操作系统中的初始化进程,负责启动和管理系统中的进程。通过 init 进程,系统可以控制和监视守护进程,确保它们在系统运行期间一直可用。

在 Linux 中,有三种主要的方式来创建进程:
fork() 方法: 使用 fork() 函数创建一个新的进程,新进程是父进程的副本。新进程和父进程有相同的环境,但是拥有不同的 PID(进程标识符)。在 Linux 环境下,fork() 是通过写时复制(copy-on-write)实现的。这意味着新进程与父进程共享相同的内存,只有在其中一个进程进行修改时,系统才会为修改后的数据生成副本。
system() 方法: 使用 system() 函数调用 /bin/sh -c command 来执行指定的命令。该函数会阻塞当前进程的执行,直到执行的命令完成。新的子进程会获得新的 PID。
exec() 方法: 使用 exec() 函数有多种不同的变体,但总体思路是用新的进程替代当前进程。通过执行 exec() 函数后,系统会以新的进程执行,新进程将继承原进程的 PID。与 fork() 不同,exec() 不会创建一个完全独立的进程,而是替代当前进程的映像。
这些方式提供了不同的进程创建和替代机制,开发者可以根据具体需求选择适当的方法。
由于 Linux 是一个支持多用户的操作系统,这意味着不同的用户可以在同一系统上运行各种不同的程序。为了唯一标识系统上运行的每个程序实例,内核使用进程 ID(PID)和父进程的进程 ID(PPID)来标识每个进程。
进程可以根据它们的 PID 和 PPID 进行分类,这样我们可以将进程分为以下几类:
父进程 - 这些是在运行时创建其它进程的进程。
子进程 - 这些是在运行时由其它进程创建的进程。
init 进程是系统中所有进程的父进程,它是启动 Linux 系统后第一个运行的程序;它管理着系统上的所有其它进程。它由内核自身启动,因此理论上说它没有父进程。
init 进程的进程 ID 总是为 1。它是所有子进程的父进程。(和根目录和子目录关系类似,一切从跟开始,一切从init进程开始)。
你可以用 pidof 命令查找某个进程的进程 ID:
[root@yfq-test ~]# pidof systemd
1
[root@yfq-test ~]# pidof python3
9117 9115
[root@yfq-test ~]#
要查找当前 shell 的进程 ID 以及它父进程的进程 ID,可以运行:
[root@yfq-test ~]# echo $$
15206
[root@yfq-test ~]# echo $PPID
15203
[root@yfq-test ~]#
在 Linux 中启动进程
每当你运行一个命令或程序,系统就会启动一个新的进程。你可以通过以下方式启动一个前台(交互式)进程,它会与当前终端连接,允许用户向其发送输入:
执行命令时不使用后台运行标志。
该进程将在当前终端中执行,且该终端将被该进程占用。
用户可以直接与该进程进行交互,通过终端发送输入给它,并观察其输出。
linux后台任务
要在后台(非交互式)启动一个进程,使用 & 符号,此时,该进程不会从用户中读取输入,直到它被移到前台。
[root@yfq-test ~]# ping -c 20000 g.cn &
[1] 19887
[root@yfq-test ~]# PING g.cn (220.181.174.34) 56(84) bytes of data.
64 bytes from 220.181.174.34 (220.181.174.34): icmp_seq=1 ttl=110 time=36.1 ms
64 bytes from 220.181.174.34 (220.181.174.34): icmp_seq=2 ttl=110 time=36.1 ms
64 bytes from 220.181.174.34 (220.181.174.34): icmp_seq=3 ttl=110 time=36.2 ms
64 bytes from 220.181.174.34 (220.181.174.34): icmp_seq=4 ttl=110 time=36.1 ms
[root@yfq-test ~]# jobs
[root@yfq-test ~]# 64 bytes from 220.181.174.34 (220.181.174.34): icmp_seq=14 ttl=110 time=36.1 ms
j64 bytes from 220.181.174.34 (220.181.174.34): icmp_seq=15 ttl=110 time=36.1 ms
[1]+ Running ping -c 20000 g.cn &
你也可以使用 Ctrl + Z 暂停执行一个程序并把它发送到后台,它会给进程发送 SIGSTOP 信号,从而暂停它的执行;它就会变为空闲:
# tar -cf backup.tar /backups/* ### 按下 Ctrl+Z
# jobs
要在后台继续运行上面被暂停的命令,使用 bg 命令:
# bg
要把后台进程发送到前台,使用 fg 命令以及任务的 ID,类似:
# jobs
# fg %1
Linux 中进程的状态
在执行过程中,一个进程会根据其环境的不同而转换到不同的状态。在 Linux 中,一个进程可能处于以下几种可能的状态:
Running(运行中):此时进程正在执行(它是系统中的当前进程)或者准备运行(正在等待分配 CPU 时间片)。
Waiting(等待中):进程正在等待某个事件的发生或者系统资源的分配。内核进一步区分为可中断等待进程(interruptible waiting processes,可以被信号中断)和不可中断等待进程(uninterruptible waiting processes,等待硬件条件,不能被中断)。
Stopped(停止中):进程已经被停止,通常是由于收到了一个信号,例如正在被调试的进程。
Zombie(僵尸):该进程已经终止,但其进程表中仍然存在条目。
有许多 Linux 工具可用于查看或列出系统中正在运行的进程,其中两个传统而广为人知的是 ps 和 top 命令:
1. ps 命令
它显示被选中的系统中活跃进程的信息,如下图所示:
[root@yfq-test ~]# ps -e |head
PID TTY TIME CMD
1 ? 00:31:09 systemd
2 ? 00:00:00 kthreadd
4 ? 00:00:00 kworker/0:0H
6 ? 00:00:03 ksoftirqd/0
7 ? 00:00:09 migration/0
8 ? 00:00:00 rcu_bh
9 ? 00:18:44 rcu_sched
10 ? 00:00:00 lru-add-drain
11 ? 00:00:23 watchdog/0
[root@yfq-test ~]#
2. top - 系统监控工具
top 是一个强大的工具,它能给你提供 运行系统的动态实时视图,如下面截图所示:
# top

3. glances - 系统监控工具
glances 是一个相对比较新的系统监控工具,它有一些比较高级的功能:
[root@yfq-test ~]# yum install glances -y
# glances

如何在 Linux 中控制进程
Linux 也有一些命令用于控制进程,例如 kill、pkill、pgrep 和 killall,下面是一些如何使用它们的基本事例:
$ pgrep -u test top
$ kill 2308
$ pgrep -u test top
$ pgrep -u test glances
$ pkill glances
$ pgrep -u test glances
给进程发送信号
Linux 中控制进程的基本方法是给它们发送信号。你可以发送很多信号给一个进程,运行下面的命令可以查看所有信号:
[root@yfq-test ~]# kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL10) SIGUSR1
11) SIGSEGV12) SIGUSR213) SIGPIPE14) SIGALRM15) SIGTERM
16) SIGSTKFLT17) SIGCHLD18) SIGCONT19) SIGSTOP20) SIGTSTP
21) SIGTTIN22) SIGTTOU23) SIGURG24) SIGXCPU25) SIGXFSZ
26) SIGVTALRM27) SIGPROF28) SIGWINCH29) SIGIO30) SIGPWR
31) SIGSYS34) SIGRTMIN35) SIGRTMIN+136) SIGRTMIN+237) SIGRTMIN+3
38) SIGRTMIN+439) SIGRTMIN+540) SIGRTMIN+641) SIGRTMIN+742) SIGRTMIN+8
43) SIGRTMIN+944) SIGRTMIN+1045) SIGRTMIN+1146) SIGRTMIN+1247) SIGRTMIN+13
48) SIGRTMIN+1449) SIGRTMIN+1550) SIGRTMAX-1451) SIGRTMAX-1352) SIGRTMAX-12
53) SIGRTMAX-1154) SIGRTMAX-1055) SIGRTMAX-956) SIGRTMAX-857) SIGRTMAX-7
58) SIGRTMAX-659) SIGRTMAX-560) SIGRTMAX-461) SIGRTMAX-362) SIGRTMAX-2
63) SIGRTMAX-164) SIGRTMAX
[root@yfq-test ~]#

要向进程发送信号,可以使用之前提到的 kill、pkill 或 pgrep 命令。但是,只有在程序中被编写为能够识别这些信号时,进程才能够响应这些信号。
以下是一些对系统用户非常有用的信号:
SIGHUP (1):当控制终端关闭时给进程发送的信号。
SIGINT (2):当用户使用 Ctrl+C 中断进程时,控制终端会发送给进程的信号。
SIGQUIT (3):当用户发送退出信号 Ctrl+D 时给进程发送的信号。
SIGKILL (9):这个信号会立即中断(杀死)进程,进程不会进行清理操作。
SIGTERM (15):这是一个用于程序终止的信号,kill 命令默认发送这个信号。
SIGTSTP (20):控制终端发送给进程的信号,要求它停止(终端停止);用户通过按下 Ctrl+Z 触发。
以下是在 Firefox 应用程序僵死时通过其 PID 杀死它的 kill 命令的示例:
bashCopy code$ pidof firefox
$ kill -9 2687
# 或者
$ kill -KILL 2687
# 或者
$ kill -SIGKILL 2687
使用它的名称杀死应用,可以像下面这样使用 pkill 或 killall:
$ pkill firefox
$ killall firefox
在 Linux 系统中,所有活跃进程都有一个优先级以及 nice 值。有比点优先级进程有更高优先级的进程一般会获得更多的 CPU 时间。
但是,有 root 权限的系统用户可以使用 nice 和 renice 命令影响(更改)优先级;在 top 命令的输出中, NI 显示了进程的 nice 值:
$ top

使用 nice 命令为一个进程设置 nice 值。记住一个普通用户可以给他拥有的进程设置 0 到 20 的 nice 值。
只有 root 用户可以使用负的 nice 值。要重新设置一个进程的优先级,像下面这样使用 renice 命令:
$ renice +8 2687
$ renice +8 2103

添加博主
微信号|yfq940-
原文作者:步步运维步步坑;如有侵权,请联系管理员删除。