Linux 进程管理
进程介绍
补充:
- 程序:没有运行的可执行文件。
- 软件:包含程序、手册、配置文件等全套的东西。软件工程。
- 进程:程序运行后,会使用cpu、内存、磁盘、网络等资源。
- 线程:将程序划分成更小的执行单元。
进程是什么
进程是已启动的可执行程序的运行中实例。
进程由以下组成部分:
- 已分配内存的地址空间
- 安全属性,包括所有权凭据和特权
- 程序代码的一个或多个执行线程
- 进程状态
进程的环境包括:
- 本地和全局变量
- 当前调度上下文
- 分配的系统资源,如文件描述符和网络端口
进程产生-fork

# 当前bash中执行sleep,此时的sleep进程就是通过fork产生
# sleep进程是bash进程的子进程
[pengyuyan@centos7 ~]$ sleep 5
进程状态
补充:操作系统主要职责。


查看进程-ps
**作用:**查看系统中进程信息
语法:ps [选项]
ps 命令选项分为两类:
- 限定查看哪些进程,用来选择进程。
- 对选定的进程查看他们哪些属性。
支持三种版本选项:
- UNIX,使用单个 –
- GNU,使用两个 —
- BSD,不使用 –
常用命令:
| ps aux | 显示所有进程的详细信息 | 最常用,看所有进程的状态 |
| ps -ef | 显示所有进程的完整格式 | 查看进程的父进程ID(PPID) |
| ps -eo | 自定义输出格式 | 只看你想看的字段 |
常见选项:
| -f | 显示完整格式 |
| -u 用户名 | 显示指定用户的进程 |
| -p PID | 显示指定PID的进程 |
| -o 字段列表 | 自定义输出格式 |
| –sort=字段 | 按指定字段排序 |
| –forest | 以树形结构显示进程父子关系 |
| u | 显示详细信息 |
| x | 显示没有控制终端的进程 |
| f | 显示进程树 |
[pengyuyan@centos7 ~]$ ps -e
PID TTY TIME CMD
1 ? 00:00:02 systemd
2 ? 00:00:00 kthreadd
4 ? 00:00:00 kworker/0:0H
6 ? 00:00:00 ksoftirqd/0
... ...
# PID,进程ID
# TTY,进程所在终端
# TIME,进程使用cpu的有效时间,并不是程序的运行时间。
# CMD,进程名称
[pengyuyan@centos7 ~]$ ps -ef |head -n 5
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 08:45 ? 00:00:02 /usr/lib/systemd/systemd –switched-root –system –deserialize 22
root 2 0 0 08:45 ? 00:00:00 [kthreadd]
root 4 2 0 08:45 ? 00:00:00 [kworker/0:0H]
root 6 2 0 08:45 ? 00:00:00 [ksoftirqd/0]
# UID,进程的执行者
# PPID,进程的父进程ID
# C,进程消耗的CPU百分比
# STIME,进程的开始执行的时刻
查看特定用户运行的进程
| BSD风格 | ps u -U pengyuyan |
[pengyuyan@centos7 ~]$ ps -u pengyuyan u
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
pengyuyan 2810 0.0 0.2 89844 9912 ? Ss 10:16 0:00 /usr/lib/systemd/systemd –user
pengyuyan 2816 0.0 0.1 235408 5332 ? S 10:16 0:00 (sd-pam)
pengyuyan 2831 0.0 0.2 1038956 10400 ? Ssl 10:16 0:00 /usr/bin/pulseaudio –daemonize=no –log-target=journal
......
查看特定终端中进程
[pengyuyan@centos7 ~]$ ps -t pts/1 u
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
pengyuyan 2843 0.0 0.1 226452 5396 pts/1 Ss 10:16 0:00 -bash
pengyuyan 4233 0.0 0.0 257508 3952 pts/1 R+ 10:40 0:00 ps -t pts/1 u
查看所有进程
[pengyuyan@centos7 ~]$ ps axu
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.3 183984 14136 ? Ss 08:55 0:02 /usr/lib/systemd/systemd –switched-root –system –deserialize 18
root 2 0.0 0.0 0 0 ? S 08:55 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? I< 08:55 0:00 [rcu_gp]
root 4 0.0 0.0 0 0 ? I< 08:55 0:00 [rcu_par_gp]
...
查看进程树
[pengyuyan@centos7 ~]$ ps axf
PID TTY STAT TIME COMMAND
2 ? S 0:00 [kthreadd]
3 ? I< 0:00 \\_ [rcu_gp]
......
1159 ? Ss 0:00 /usr/sbin/sshd -D -oCiphers=aes256-gcm@openssh.com,chacha20-poly1305@op
2033 ? Ss 0:00 \\_ sshd: root [priv]
2064 ? S 0:00 | \\_ sshd: root@pts/0
2075 pts/0 Ss 0:00 | \\_ -bash
2950 pts/0 S+ 0:00 | \\_ man ps
2963 pts/0 S+ 0:00 | \\_ less
2800 ? Ss 0:00 \\_ sshd: pengyuyan [priv]
2833 ? S 0:00 \\_ sshd: pengyuyan@pts/1
2843 pts/1 Ss 0:00 \\_ -bash
4278 pts/1 R+ 0:00 \\_ ps axf
......
查看特定进程特定属性
# 通过PID限定
[pengyuyan@centos7 ~]$ ps -o pid,%cpu,%mem,command 1159
PID %CPU %MEM COMMAND
1159 0.0 0.1 /usr/sbin/sshd -D -oCiphers=aes256-gcm@openssh.com,chacha20-poly1305@openssh.com...
# 通过命令名称限定
[pengyuyan@centos7 ~]$ ps -C passwd -o pid,ruser,euser,command
PID RUSER EUSER COMMAND
4420 pengyuyan root passwd
对进程进行排序,–sort %cpu升序 ,–sort -%cpu降序
[pengyuyan@centos7 ~]$ ps axu –sort -%cpu
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1786 0.4 5.1 1092936 205568 ? Ssl 08:55 0:34 /usr/libexec/packagekitd
pengyuyan 3356 0.3 4.9 3042676 197256 tty2 Sl+ 10:36 0:03 /usr/bin/gnome-shell
root 1150 0.1 0.8 618372 32088 ? Ssl 08:55 0:12 /usr/libexec/platform-python -Es /usr/sbin/tuned -l -P
pengyuyan 3728 0.1 2.7 1379632 109476 tty2 Sl+ 10:36 0:01 /usr/bin/gnome-software –gapplication-service
......
控制 jobs
作业控制允许单个shell实例运行和管理多个命令。
- 前台进程,一个终端中只有一个前台进程,该进程可以终端窗口中读取输入和响应键盘生成的信号。
- 后台进程,在后台运行的进程,该进程不能从终端读取输入或接收键盘产生的中断。后台进程可能暂停,也可能正在运行。如果正在运行的后台作业尝试从终端读取,它将自动暂停。在ps列表中,tty终端列显示的是?号,那么该进程肯定是后台进程,但并代表显示为其他终端的进程就不是后台进程。
相关命令:
启动后台动作:在命令行末尾加 &
查看当前作业:jobs
| [1] | 作业号 |
| – | 该作业是"当前作业"之前的一个 |
| + | 该作业是"当前作业" |
| Running/Stopped | 作业状态 |
| & | 表示在后台运行 |
把后台作业调回前台:fg
1°把最近一个后台作业调回前台
fg
2°把指定作业号调到前台
fg %1
暂停前台作业并转入后台:CTRL+Z
让暂停的作业继续在后台运行:bg
1°让最近一个暂停的作业在后台继续运行
bg
2°让指定作业在后台继续运行
bg %1
示例:
# 准备脚本
[root@centos7 ~]# cat << 'EOF' > /usr/local/bin/study
#!/bin/bash
while true
do
echo "$(date): I'm studying [ $@ ]" >> study.log
sleep 1
done
EOF
[root@centos7 ~]# chmod +x /usr/local/bin/study
# 任何一个进程都可以在后台启动,通过增加一个&符号。
# bash会显示job号和进程的PID。shell不需要等待子进程运行结束,而可以继续运行其他命令。
[pengyuyan@centos7 ~]$ study Linux &
[1] 67307
[pengyuyan@centos7 ~]$ jobs
[1]+ 运行中 study Linux &
# 新开窗口动态监控文件study.log内容
[pengyuyan@centos7 ~]$ tail -f study.log
# 以前台方式运行
[pengyuyan@centos7 ~]$ study Python
# ctrl+Z 暂停前台进程
[pengyuyan@centos7 ~]$ study Python
^Z
[2]+ 已停止 study Python
[pengyuyan@centos7 ~]$ jobs
[1]– 运行中 study Linux &
[2]+ 已停止 study Python
# 将job2放到后台运行
[pengyuyan@centos7 ~]$ bg %2
[2]+ study Python &
[pengyuyan@centos7 ~]$ jobs
[1]– 运行中 study Linux &
[2]+ 运行中 study Python &
# 以后台方式运行
[pengyuyan@centos7 ~]$ study MySQL &
[3] 67745
清理实验:
# 前台运行的进程,按ctrl+c终止进程运行
[pengyuyan@centos7 ~]$ fg %1
study Linux
^C
[pengyuyan@centos7 ~]$ fg %2
study Python
^C
[pengyuyan@centos7 ~]$ fg %3
study MySQL
^C
[pengyuyan@centos7 ~]$ jobs
思考: passwd命令是否在后台运行?
答:需要交互的进程是无法在后台运行的。
[pengyuyan@centos7 ~]$ passwd &
[3] 3135
[pengyuyan@centos7 ~]$ 更改用户 pengyuyan 的密码 。
[1]+ 已停止 passwd
思考:如何避免意外断网和关闭终端,导致终端中后台运行的进程终止?
例如:服务器在国外,给服务器打补丁包,打补丁大概需要2个小时。
方法一:nohub commnad &
[pengyuyan@centos7 ~]$ nohup study English &
nohup 命令
**作用:**让进程在后台运行,并且不受终端关闭影响
**语法:**nohup 命令 [参数] &
默认行为:
| 后台运行 | 通常配合&使用,让进程在后台运行,释放终端 |
查看nohup启动的进程:
jobs -l
ps aux | grep script.sh
终止nohup启动的进程:
ps aux | grep script.sh
kill -15 PID或强行终止(kill -9 PID)
方法二:screen
# 先配置epel仓库
[root@centos7 ~]# curl -s -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
[root@centos7 ~]# yum install -y screen
# 开启一个screen
[pengyuyan@centos7 ~]$ screen
[pengyuyan@centos7 ~]$ sleep 1234
# 再启动一个终端,查看screen
[pengyuyan@centos7 ~]$ screen -ls
There is a screen on:
40398.pts-7.centos7 (Attached)
1 Socket in /run/screen/S-pengyuyan.
# 此时将执行sleep 1234 的终端关掉
# 再次查看screen
[pengyuyan@centos7 ~]$ screen -ls
There is a screen on:
40398.pts-7.centos7 (Detached)
1 Socket in /run/screen/S-pengyuyan.
# 关联到断开的screen
[pengyuyan@centos7 ~]$ screen -r 40398.pts-7.centos7
# 关闭screen会话 方式1:在screen 会话中执行 exit
# 关闭screen会话 方式2:在screen 会话外执行以下命令
# 示例:
[pengyuyan@centos7 ~]$ screen -X -S 40398.pts-7.centos7 quit
# 关闭screen会话 方式3:使用 kill 命令
# 40398.pts-7.centos7中的40398是screen进程的pid
[pengyuyan@centos7 ~]$ kill 40398
screen命令
**作用:**可以在一个终端窗口中创建多个独立的会话,并且即使你关闭终端或断开SSH连接,这些会话的进程任然会继续运行
用法:
启动一个新screen会话
screen -S mysession
执行当前目录下的一个shell脚本
./long_task.sh
按CTRL+A然后按D暂时脱离会话,进程继续运行
重新连接到这个会话
screen -r mysession
查看所有screen会话的方式
screen -ls
关闭screen会话的方式:
提示:每个用户管理自己的screen会话,root用户也无法看到其他用户screen清单。
给进程发信号
信号介绍
signal 是传递给进程的软中断。
生成信号的事件可以是错误,外部事件或者使用信号发送命令或键盘序列。

kill 命令
作用:给进程发信号
语法:kill [选项] PID
常用信号速查表:
| 1 | HUP | 挂起,常用于重新加载配置文件 |
| 2 | INT | 键盘中断(等价于ctrl+c) |
| 3 | QUIT | 退出,并生成核心转储(等价于ctrl+\\) |
| 9 | KILL | 强制杀死,无法拦截 |
| 15 | TERM | 正常终止(默认信号,推荐) |
| 18 | CONT | 继续运行(恢复被暂停的进程) |
| 19 | STOP | 暂停进程(无法被拦截) |
| 20 | TSTP | 键盘暂停(等价于ctrl+z) |
如何找到要杀的PID?
ps aux | grep 进程名
# 准备脚本
# 准备脚本
[root@centos7 ~]# cat << 'EOF' > /usr/local/bin/study
#!/bin/bash
while true
do
echo "$(date): I'm studying [ $@ ]" >> study.log
sleep 1
done
EOF
[root@centos7 ~]# chmod +x /usr/local/bin/study
# 新开窗口动态监控文件study.log内容
[pengyuyan@centos7 ~]$ tail -f study.log
# 创建进程
[pengyuyan@centos7 ~]$ study Linux &
[1] 3340
[pengyuyan@centos7 ~]$ study Python &
[2] 3341
# 查看信号清单
[pengyuyan@centos7 ~]$ 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
# 给job id为1的进程发19信号,暂停运行
[pengyuyan@centos7 ~]$ kill -19 %1
[pengyuyan@centos7 ~]$ jobs
[1]+ 已停止 study Linux
[2]– 运行中 study Python &
# 给job id为1的进程发18信号,继续运行
[pengyuyan@centos7 ~]$ kill -18 %1
[pengyuyan@centos7 ~]$ jobs
[1]+ 运行中 study Linux &
[2]– 运行中 study Python &
# 给job id为2的进程发SIGTERM信号,终止程序运行,该信号是默认信号
[pengyuyan@centos7 ~]$ kill -SIGTERM %2
[pengyuyan@centos7 ~]$ jobs
[1]+ 运行中 study Linux &
[2]– 已终止 study Python
[pengyuyan@centos7 ~]$ jobs
[1]+ 运行中 study Linux &
# SIGTERM 信号是默认信号
[pengyuyan@centos7 ~]$ kill %1
[pengyuyan@centos7 ~]$ jobs
[1]+ 已终止 study Linux
[pengyuyan@centos7 ~]$ jobs
# 给PID是10123的进程发默认信号
[pengyuyan@centos7 ~]$ study MySQL &
[1] 10123
[pengyuyan@centos7 ~]$ ps axu|grep study
pengyuyan 10123 0.0 0.0 113284 1416 pts/4 S 14:53 0:00 /bin/bash study MySQL
pengyuyan 10157 0.0 0.0 112824 984 pts/4 R+ 14:53 0:00 grep –color=auto study
[pengyuyan@centos7 ~]$ kill 10123
[pengyuyan@centos7 ~]$ jobs
[1]+ 已终止 study MySQL
pkill 和 pgrep 命令
pgrep
**作用:**按进程查找进程PID
**语法:**pgrep [选项] 进程名
常见选项:
| -u 用户名 | 查找属于某用户的进程 | pgrep -u tony |
| -U UID | 按用户ID查找 | pgrep -U 1000 |
| -t 终端 | 查找在指定终端运行的进程 | pgrep -t pts/0 |
| -l | 显示PID和进程名 | pgrep -l sshd |
| -a | 显示PID和完整命令(含参数) | pgrep -a nginx |
| -f | 匹配完整命令行(不仅仅是进程名) | pgrep -f ‘python3 script.py’ |
| -n | 只返回最新启动的进程 | pgrep -n sshd |
| -o | 只返回最早启动的进程 | pgrep -o sshd |
| -x | 精确匹配进程名(不含子串) | pgrep -x sshd(不会匹配sshd_confing) |
| -P PPID | 查找父进程ID为指定值的子进程 | pgrep -P 1234 |
pkill
**作用:**按条件发送信号给进程
**语法:**pkill [选项] 进程名
常用选项:
| -u 用户名 | 终止属于某用户的所有进程 | pkill -u tony |
| -t 终端 | 终止在指定终端运行的所有进程 | pkill -f pts/0 |
| -f | 匹配完整命令行 | pkill -f “python3 script.py” |
| -x | 精确匹配进程名 | pkill -x sshd |
| -n | 只杀死最新启动的进程 | pkill -n sshd |
| -o | 只杀死最早启动的进程 | pkill -o sshd |
| -P PPID | 杀死指定父进程的所有子进程 | pkill -P 1234 |
| -信号 | 指定要发送的信号(如 -9、-15) | pkill -9 nginx |
| –signal 信号 | 同 -信号 | pkill –signal KILL nginx |
# 准备
[pengyuyan@centos7 ~]$ sleep 1231 & sleep 1232 & sleep 1233 &
[1] 3517
[2] 3518
[3] 3519
# 根据进程名查找进程
[pengyuyan@centos7 ~]$ pgrep sleep
3517
3518
3519
[pengyuyan@centos7 ~]$ pgrep -l sleep
3517 sleep
3518 sleep
3519 sleep
[pengyuyan@centos7 ~]$ ps axu|grep sleep
pengyuyan 3517 0.0 0.0 108052 356 pts/2 S 11:35 0:00 sleep 1231
pengyuyan 3518 0.0 0.0 108052 356 pts/2 S 11:35 0:00 sleep 1232
pengyuyan 3519 0.0 0.0 108052 356 pts/2 S 11:35 0:00 sleep 1233
pengyuyan 3523 0.0 0.0 112824 976 pts/2 S+ 11:35 0:00 grep –color=auto sleep
# 给sleep相关进程发默认信号
[pengyuyan@centos7 ~]$ pkill sleep
[1] 已终止 sleep 1231
[2]– 已终止 sleep 1232
[3]+ 已终止 sleep 1233
[pengyuyan@centos7 ~]$ ps axu|grep sleep
pengyuyan 3535 0.0 0.0 112824 980 pts/2 R+ 11:36 0:00 grep –color=auto sleep
# 根据用户名匹配程序
[pengyuyan@centos7 ~]$ ps -u pengyuyan
PID TTY TIME CMD
3403 ? 00:00:00 sshd
3404 pts/2 00:00:00 bash
3544 pts/2 00:00:00 ps
[pengyuyan@centos7 ~]$ pgrep -u pengyuyan
3403
3404
# kill相应用户所有进程,也就是注销用户
[root@centos7 ~]# pkill -u pengyuyan
# 根据终端匹配
[pengyuyan@centos7 ~]$ sleep 1231 & sleep 1232 &
[1] 3607
[2] 3608
[pengyuyan@centos7 ~]$ tty
/dev/pts/0
[pengyuyan@centos7 ~]$ pgrep -t pts/0 -l
3555 bash
3607 sleep
3608 sleep
[pengyuyan@centos7 ~]$ pkill -t pts/0
[1]– 已终止 sleep 1231
[2]+ 已终止 sleep 1232
# 给bash发默认信号,bash进程屏蔽了
[pengyuyan@centos7 ~]$ pkill 3555
# 根据PPID,给子进程发信号
[pengyuyan@centos7 ~]$ sleep 1231 & sleep 1232 &
[1] 3708
[2] 3709
[pengyuyan@centos7 ~]$ ps jf
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
3663 3664 3664 3664 pts/0 3711 Ss 1000 0:00 -bash
3664 3708 3708 3664 pts/0 3711 S 1000 0:00 \\_ sleep 1231
3664 3709 3709 3664 pts/0 3711 S 1000 0:00 \\_ sleep 1232
3664 3711 3711 3664 pts/0 3711 R+ 1000 0:00 \\_ ps jf
[pengyuyan@centos7 ~]$ pkill -P 3664
[1]– 已终止 sleep 1231
[2]+ 已终止 sleep 1232
如果pgrep无法过滤出具有特定特征的进程,使用ps和kill配合完成。
# 环境准备
# 暂停多个 yum 安装进程
[root@centos7 ~]# yum install httpd # 按ctrl+Z
[root@centos7 ~]# yum install httpd # 按ctrl+Z
[root@centos7 ~]# yum install httpd # 按ctrl+Z
[root@centos7 ~]# ps axu | grep yum
root 8191 0.8 2.9 631840 115748 pts/0 T 11:09 0:00 /usr/libexec/platform-python /usr/bin/yum install httpd
root 8193 0.8 2.8 631840 114060 pts/0 T 11:09 0:00 /usr/libexec/platform-python /usr/bin/yum install httpd
root 8195 0.8 2.8 631840 115336 pts/0 T 11:09 0:00 /usr/libexec/platform-python /usr/bin/yum install httpd
root 8221 0.0 0.0 222016 1104 pts/0 S+ 11:10 0:00 grep –color=auto yum
[root@centos7 ~]# ps axu | grep yum |grep -v grep | awk '{print $2}'
8191
8193
8195
[root@centos7 ~]# kill -9 $(ps axu | grep yum |grep -v grep | awk '{print $2}')
# 或者
[root@centos7 ~]# pkill -9 yum
# 或者
[root@centos7 ~]# kill -9 $(pgrep yum)
whoami-who-w-last 命令
| whoami | 显示当前登录的用户名 | 当前用户 | 进程信息 |
| who | 显示当前已登录的用户列表 | 当前在线用户 | /var/run/utmp |
| w | 显示当前登录用户 + 正在执行的命令 + 系统负载 | 当前在线用户 + 系统状态 | /var/run/utmp + 进程信息 |
| last | 显示历史登录记录(含关机、重启) | 历史登录记录 | /var/log/wtmp |
# 当前系统登录的用户
[pengyuyan@centos7 ~]$ whoami
pengyuyan
# 当前系统登录的用户详细信息
[pengyuyan@centos7 ~]$ who
pengyuyan pts/0 2024-07-23 14:54 (10.1.8.1)
pengyuyan pts/1 2024-07-23 14:56 (10.1.8.1)
root pts/3 2024-07-23 14:17 (10.1.8.1)
# 当前系统登录的用户详细信息
[pengyuyan@centos7 ~]$ w
15:04:35 up 6:08, 4 users, load average: 0.00, 0.02, 0.02
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
pengyuyan pts/0 10.1.8.1 14:54 1.00s 0.14s 0.00s w
pengyuyan pts/1 10.1.8.1 14:56 2:27 0.01s 0.01s -bash
root pts/3 10.1.8.1 14:17 10:11 0.04s 0.04s -bash
# 系统中用户登录记录
[pengyuyan@centos7 ~]$ last
pengyuyan pts/0 10.1.8.1 Wed Nov 9 11:42 still logged in
pengyuyan pts/0 10.1.8.1 Wed Nov 9 11:37 – 11:41 (00:03)
pengyuyan pts/2 10.1.8.1 Wed Nov 9 11:31 – 11:37 (00:05)
root pts/1 10.1.8.1 Wed Nov 9 10:06 still logged in
pengyuyan pts/0 10.1.8.1 Wed Nov 9 08:50 – 11:31 (02:40)
reboot system boot 3.10.0-1160.el7. Wed Nov 9 08:45 – 11:51 (03:05)
... ...
pengyuyan pts/0 10.1.8.1 Fri Nov 4 09:51 – 14:22 (04:31)
reboot system boot 3.10.0-1160.el7. Fri Nov 4 09:05 – 11:51 (5+02:45)
pengyuyan :0 :0 Thu Nov 3 09:47 – crash (23:18)
reboot system boot 3.10.0-1160.el7. Thu Nov 3 09:42 – 11:51 (6+02:08)
wtmp begins Thu Nov 3 09:42:18 2022
案例:kill 不掉的进程
一个进程杀掉之后,又出现了。怎么让这个程序永久 kill 掉?
模拟:
# 准备程序
[pengyuyan@centos7 ~]$ mkdir bin
[pengyuyan@centos7 ~]$ cat > bin/mm <<EOF
#!/bin/bash
while true
do
md5sum /dev/zero
sleep 1
done
EOF
[pengyuyan@centos7 ~]$ chmod +x bin/mm
# 执行程序
[pengyuyan@centos7 ~]$ nohup mm &
处理过程
# 查找进程
[pengyuyan@centos7 ~]$ ps axo pid,%cpu,command –sort -%cpu |head -n 5
PID %CPU COMMAND
73712 99.7 md5sum /dev/zero
1150 0.1 /usr/libexec/platform-python -Es /usr/sbin/tuned -l -P
1786 0.1 /usr/libexec/packagekitd
69280 0.1 /usr/bin/gnome-shell
# kill 进程,再次查看
[pengyuyan@centos7 ~]$ kill 73712
[pengyuyan@centos7 ~]$ ps axo pid,%cpu,command –sort -%cpu |head -n 5
PID %CPU COMMAND
74830 99.8 md5sum /dev/zero
1150 0.1 /usr/libexec/platform-python -Es /usr/sbin/tuned -l -P
1786 0.1 /usr/libexec/packagekitd
69280 0.1 /usr/bin/gnome-shell
# 思路一:把 md5sum 程序删除,使用 mv 模拟
[root@centos7 ~]# mv /bin/md5sum ./md5sum
# 移回去
# [root@centos7 ~]# mv ./md5sum /bin/md5sum
# 思路二:找到幕后推手,也就是找到父进程
[root@centos7 ~]# ps ax -f |grep -e md5sum -e PPID
UID PID PPID C STIME TTY STAT TIME CMD
pengyuyan 75538 73556 99 15:25 ? R 2:12 md5sum /dev/zero
root 76070 53920 0 15:28 pts/3 R+ 0:00 grep –color=auto -e md5sum -e PPID
[root@centos7 ~]# kill 73556 75538
特殊进程
参考:出处
僵尸进程
僵尸进程介绍
如果一个进程退出了,立马X状态,作为父进程没有机会拿到子进程的退出结果。所以在Linux中,一般进程不会立即退出,而是要维持一个状态叫做Z,也叫做僵尸状态,方便后续父进程读取该子进程的退出结果。
僵尸状态会以终止状态保持在进程列表中,并且会一直等待父进程读取退出状态码。所以只要子进程退出,父进程还在运行,但是父进程没有读取子进程状态,子进程就进入Z状态。
僵尸进程模拟
可以使用实验来模拟僵尸状态:fork一个子进程,让子进程先退出,但是不要回收子进程。
写一段代码,让父进程运行60s,子进程运行10s,此时子进程先退出,父进程还在运行,同时父进程没有获取到子进程的退出码,子进程进入僵尸状态。
zombies.c 代码如下:
[root@centos7 ~]# vim zombies.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
pid_t id = fork();
//创建失败
if(id<0)
{
perror("fork");
return 1;
}
// id >0 运行父进程 父进程运行30s
else if(id>0)
{
//parent
printf("parent[%d] is sleeping …\\n",getpid());
sleep(60);
}
// id == 0 运行子进程, 子进程运行 5s
else {
printf("child[%d] is begin Z …\\n",getpid());
sleep(10);
exit(EXIT_SUCCESS);
}
return 0;
}
# 安装 gcc 软件
[root@centos7 ~]# yum install -y gcc
# 编辑源码为二进制可执行程序
[root@centos7 ~]# gcc zombies.c -o zombies
[root@centos7 ~]# chmod +x zombies
[root@centos7 ~]# ./zombies
parent[1703] is sleeping ...
child[1704] is begin Z ...
# 新开终端,执行如下命令监控
[root@centos7 ~]# while true;do ps -C zombies u;sleep 1; echo;done
......
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1703 0.0 0.0 4216 356 pts/1 S+ 00:07 0:00 ./zombies
root 1704 0.0 0.0 4216 88 pts/1 S+ 00:07 0:00 ./zombies
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1703 0.0 0.0 4216 356 pts/1 S+ 00:07 0:00 ./zombies
root 1704 0.0 0.0 4216 88 pts/1 S+ 00:07 0:00 ./zombies
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1703 0.0 0.0 4216 356 pts/1 S+ 00:07 0:00 ./zombies
root 1704 0.0 0.0 0 0 pts/1 Z+ 00:07 0:00 [zombies] <defunct>
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1703 0.0 0.0 4216 356 pts/1 S+ 00:07 0:00 ./zombies
root 1704 0.0 0.0 0 0 pts/1 Z+ 00:07 0:00 [zombies] <defunct>
......
可以看到子进程退出后,释放内存资源,状态变为 Zombies。
僵尸进程危害
进程的退出状态必须被维持下去,因为它要告诉它的父进程,你交给我的任务,我办的怎么样了,可是父进程一直不读取,那么进程就处于Z状态。
维护退出状态本身就是使用数据维护,属于进程的基本信息,所以要保存在tast_struct(PCB)中,Z状态一直不退出,PCB就需要一直维护。
那么,一个父进程创建了很多子进程,但是不回收,就会造成资源的浪费,因为数据结构对象本身就要占用内存,就比如C语言中定义一个结构体变量,就需要在内存的某个位置进行开辟空间。
太多的僵尸进程会造成PID资源浪费,无法创建新的进程,因为一个操作系统的进程总数是有上限。
孤儿进程
孤儿进程介绍
父进程如果提前退出,子进程后退出,子进程就称为孤儿进程。子进程退出后处于Z状态,系统如何处理?
此时,子进程被1号进程systemd领养,由systemd回收。
孤儿进程模拟
写一段代码,让子进程运行30s,父进程运行3s,父进程先退出,子进程由1号进程收养。
lonely.c 代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
pid_t id = fork();
if(id<0)
{
perror("fork");
return 1;
}
else if(id == 0)
{
// parent
// printf("parent[%d] is sleeping …\\n",getpid());
printf("I am child, pid:%d\\n",getpid());
sleep(60);
}
else {
// parent
printf("I am parent,pid:%d\\n",getpid());
sleep(3);
}
return 0;
}
[root@centos7 ~]# gcc lonely.c -o lonely
[root@centos7 ~]# chmod +x lonely
[root@centos7 ~]# ./lonely
I am parent,pid:1882
I am child, pid:1883
# 新开终端,执行如下命令监控
[root@centos7 ~]# while true;do ps -fC lonely;sleep 1; echo;done
......
UID PID PPID C STIME TTY TIME CMD
root 1882 1223 0 00:14 pts/1 00:00:00 ./lonely
root 1883 1882 0 00:14 pts/1 00:00:00 ./lonely
UID PID PPID C STIME TTY TIME CMD
root 1883 1 0 00:14 pts/1 00:00:00 ./lonely
....
可以看到父进程退出后,子进程的父进程的PID有原先的1882变为1了。
孤儿进程危害
**虽然孤儿进程由systemd直接管理了,但如果仍然不停产生新的孤儿进程则会导致占用过多系统资源。**需要开发人员检查代码,避免这个问题。如果孤儿进程没有实际意义,则可以通过kill或pkill终止。
监控系统负载
系统负载介绍
系统负载平均值:Linux内核以活动请求数的指数移动平均值来表示。
- 活动请求数不仅包含运行中进程,还包含等待IO的进程,对应于R和D。等待IO包括处于睡眠等待预期磁盘和网络响应的任务。
- 指数移动平均值是一个数学公式,可以平滑趋势数据的高值和低值,更加准确地表示一段时间内系统负载,并确定系统负载是随着时间增加还是减少。
- 根据所有CPU活动请求数,每5秒计算一次Load Average。通过汇总这些值,可以得到最近1分钟,5分钟和15分钟内的指数移动平均值。
- 一些UNIX系统仅考虑CPU使用率或运行队列长度。Linux中负载平均值中还包含了对IO的考量,遇到负载平均值很高但CPU活动很低时,检查磁盘和网络活动。
- Linux将各个物理CPU核心和微处理器超线程计为独立执行单元。每个独立的执行单元拥有独立的请求队列。
查看系统负载
# 查看CPU
[pengyuyan@centos7 ~]$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 2 # cpu 数量为2
On-line CPU(s) list: 0,1
Thread(s) per core: 1
Core(s) per socket: 1
socket: 2
NUMA 节点: 1
厂商 ID: GenuineIntel
CPU 系列: 6
型号: 94
型号名称: Intel(R) Core(TM) i5-6300HQ CPU @ 2.30GHz
步进: 3
CPU MHz: 2304.001
BogoMIPS: 4608.00
......
# 查看负载
[pengyuyan@centos7 ~]$ uptime
13:47:10 up 5:01, 2 users, load average: 0.00, 0.01, 0.05
# load average: 0.00, 0.01, 0.05
# 代表最近1分钟,5分钟和15分钟内的指数移动平均值。
# 给系统加负载
[pengyuyan@centos7 ~]$ md5sum /dev/zero &
[1] 4912
[pengyuyan@centos7 ~]$ md5sum /dev/zero &
[2] 4913
# 等30秒左右
[pengyuyan@centos7 ~]$ uptime
13:48:57 up 5:03, 2 users, load average: 1.02, 0.28, 0.13
负载解读
示例:4核心的CPU
-
负载为: 2.92 4.48 5.20
-
每个cpu负载为:0.73(2.92/4) 1.12(4.48/4) 1.30(5.20/4)
比较理想的值为 75% 左右。
top 命令
作用:动态查看进程信息,包括不同状态任务数量,CPU消耗和内存消耗。 
top命令快捷键
常用的命令:数字1,P,M,k,q,h。

stress 工具
Linux 中的 stress 工具用于对系统进行压力测试,可模拟 CPU、内存、I/O 和磁盘等资源的高负载状态。通过指定参数(如 -c 压 CPU、-m 压内存)可创建负载,帮助发现系统在压力下的稳定性问题,常用于性能调优或硬件验证。
**语法:**stress [选项] [参数]
常见选项:
| -c N | 压 CPU:让 CPU 疯狂计算,模拟高负载场景 | N 表示要启动几个进程来跑满 CPU。如果你的 CPU 有 4 个核心,-c 4 就会让所有核心满载。 | stress -c 4 |
| -m N | 占内存:启动 N 个进程不断分配和占用内存 | N 表示启动几个进程来吃内存。配合 –vm-bytes 指定每个进程吃多少内存 | stress -m 2 |
| –vm-bytes N | 指定每个内存进程吃多少内存(必须和 -m 一起用) | N 可以带单位,如 256M(256兆)、1G(1GB)。表示每个进程吃掉 256MB 内存。 | stress -m 2 –vm-bytes 256M |
| –vm-keep | 让内存进程一直占着内存不释放(模拟内存泄漏场景) | 不加这个选项,内存会反复分配和释放;加了之后,内存会被持续占用,模拟内存不足的情况。 | stress -m 2 –vm-bytes 256M –vm-keep |
| -d N | 压硬盘:启动 N 个进程不断写入和删除临时文件 | N 表示启动几个进程来读写硬盘。配合 –hdd-bytes 指定每个进程写多少数据。 | stress -d 1 |
| –hdd-bytes N | 指定每个磁盘进程写入多少数据(必须和 -d 一起用) | N 可以带单位,如 100M、1G。表示每个进程写入 1GB 的临时文件,把硬盘跑满。 | stress -d 1 –hdd-bytes 1G |
| -i N | 压 I/O:启动 N 个进程频繁调用 sync(),制造磁盘处理瓶颈 | N 表示启动几个进程来制造 I/O 等待。它不读写大文件,而是让硬盘忙于处理零碎的“同步”请求。 | stress -i 4 |
| -t N | 设置测试运行多长时间后自动停止 | N 可以带单位,如 60s(60秒)、1m(1分钟)、1h(1小时)。时间到后自动退出。 | stress -c 4 -t 60s |
| -v | 显示详细运行信息(适合调试) | 不加的话,stress 默认不输出任何信息;加上后会显示每个进程的状态。 | stress -c 2 -v |
| -q | 静默模式(不输出任何信息) | 适合在后台脚本中运行,不干扰其他输出。 | stress -c 2 -q |
| 让 CPU 满载运行 1 分钟 | stress -c 4 -t 60s | 启动 4 个进程压 CPU,1 分钟后自动停止 |
| 吃掉 1GB 内存(2 个进程各 512M) | stress -m 2 –vm-bytes 512M –vm-keep | 启动 2 个进程,每个占用 512MB 内存,一直占着不释放 |
| 同时压 CPU 和内存 | stress -c 2 -m 1 –vm-bytes 256M | 2 个进程压 CPU,1 个进程占 256MB 内存 |
| 压硬盘:写入 2GB 数据 | stress -d 1 –hdd-bytes 2G | 启动 1 个进程,不断写入 2GB 的临时文件 |
| 混合压力测试(CPU + 内存 + I/O) | stress -c 2 -m 1 –vm-bytes 256M -i 2 -t 2m | 2 个进程压 CPU,1 个进程占 256M 内存,2 个进程压 I/O,持续 2 分钟 |
| 安静模式运行(不输出任何信息) | stress -c 2 -q -t 30s | 压 CPU 30 秒,屏幕不显示任何内容 |
# 安装
[root@centos7 ~]# yum install -y stress
压力测试-CPU
# 消耗2个CPU
[root@centos7 ~ 14:17:19]# stress -c 2
stress: info: [2595] dispatching hogs: 2 cpu, 0 io, 0 vm, 0 hdd
# top 监控
top – 14:18:22 up 47 min, 2 users, load average: 1.37, 0.50, 0.47
Tasks: 187 total, 4 running, 183 sleeping, 0 stopped, 0 zombie
%Cpu(s):100.0 us, 0.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 4026124 total, 1535676 free, 490668 used, 1999780 buff/cache
KiB Swap: 4063228 total, 4063228 free, 0 used. 3277584 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2596 root 20 0 7312 100 0 R 100.0 0.0 1:01.42 stress
2597 root 20 0 7312 100 0 R 100.0 0.0 1:01.25 stress
2594 root 20 0 162100 2320 1588 R 0.6 0.1 0:00.12 top
......
压力测试-内存
# 消耗前内存
[root@centos7 ~ 14:21:06]# free -m
total used free shared buff/cache available
Mem: 3931 478 1500 14 1952 3201
Swap: 3967 0 3967
# 消耗 1G 内存
[root@centos7 ~ 14:19:11]# stress -m 1 –vm-bytes 1G
stress: info: [2623] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
# 消耗后内存
[root@centos7 ~ 14:21:44]# free -m
total used free shared buff/cache available
Mem: 3931 1403 575 14 1952 2274
Swap: 3967 0 3967
压力测试-磁盘
# 消耗磁盘IO
[root@centos7 ~ 14:22:21]# stress -d 1 –hdd-bytes 2G
# 监视活动状态百分比,%util
[root@centos7 ~ 14:23:28]# yum install -y sysstat
[root@centos7 ~ 14:23:31]# sar -dp 1
......
14时23分29秒 DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
14时23分30秒 sda 2699.00 0.00 2762752.00 1023.62 6.11 2.26 0.29 79.50
14时23分30秒 sr0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
14时23分30秒 centos-root 2698.00 0.00 2761728.00 1023.62 6.11 2.26 0.29 79.50
14时23分30秒 centos-swap 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
14时23分30秒 centos-home 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
......
网络测试
wget 命令
作用:是 Linux 中一个非常强大的命令行下载工具。它支持 HTTP、HTTPS 和 FTP 协议,可以在后台下载文件,即使断开终端连接也能继续运行。
**语法:**wget [选项] URL
URL即网址
常见用法:
| wget URL | 下载文件到当前目录 |
| wget -O 文件名 URL | 下载并重命名文件 |
| wget -c URL | 断点续传(续传未完成的下载) |
| wget -q URL | 静默模式(不显示进度) |
| wget -b URL | 后台下载 |
| wget -r URL | 递归下载整个网站 |
sar命令
作用:是 Linux 上一款全面的系统性能分析工具,可以收集、报告并保存 CPU、内存、磁盘 I/O、网络等多维度历史数据。它属于 sysstat 工具包,默认每 10 分钟采集一次数据,非常适合用于事后排查和性能趋势分析。
**语法:**sar [选项] [时间间隔] [采样次数]
[时间间隔]:每次采样的间隔时间(秒)
[采样次数]:总共采样的次数。若不指定,则持续输出
核心功能选项速查:
| 综合查看 | -A | 输出所有活动的统计报告 |
| 网络监控 | -n DEV | 查看网络接口的流量统计(收发包数、速率) |
| 网络监控 | -n TCP | 查看 TCP 连接状态统计 |
| 网络监控 | -n SOCK | 查看各类 Socket 数量 |
# 传送一个大size的文件
[root@centos7 ~ 14:27:17]# wget http://192.168.43.100/isos/CentOS-7-x86_64-DVD-2207-02.iso
# 监控带宽
[root@centos7 ~ 14:29:13]# sar -n DEV 1
......
14时29分07秒 IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s
14时29分08秒 ens32 69961.00 5404.00 96338.71 513.95 0.00 0.00 0.00
14时29分08秒 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00
14时29分08秒 virbr0-nic 0.00 0.00 0.00 0.00 0.00 0.00 0.00
14时29分08秒 virbr0 0.00 0.00 0.00 0.00 0.00 0.00 0.00
......
监控总结
以下是针对 Linux 系统监控的几条实用建议,涵盖关键监控维度和最佳实践:
29分08秒 virbr0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 …
## 监控总结
以下是针对 Linux 系统监控的几条实用建议,涵盖关键监控维度和最佳实践:
1. **核心指标实时监控**
重点跟踪 CPU 使用率(用户态 / 系统态占比)、内存占用(含缓存 /swap 使用率)、磁盘 I/O(读写吞吐量、IOPS)和网络流量(带宽利用率、连接数)。可通过 `top`/`htop`(实时)、`vmstat`/`iostat`(系统级)等工具快速查看。
2. **部署专业监控工具**
对于服务器集群或长期监控需求,建议使用 Prometheus + Grafana(可视化强)、Zabbix(全功能监控)或 Nagios(轻量告警)等工具,实现指标集中收集、趋势分析和历史数据查询。
3. **设置关键阈值告警**
针对核心指标配置告警阈值(如 CPU 持续 5 分钟超 80%、磁盘空间不足 10%),通过邮件、短信或即时通讯工具推送告警,避免故障扩大。注意避免告警风暴(可设置告警合并或延迟)。
4. **监控进程与服务状态**
定期检查关键服务(如 Nginx、MySQL)的运行状态、进程数及资源消耗,可通过 `systemctl status` 或自定义脚本实现。对异常退出的进程,结合日志排查崩溃原因。
5. **日志集中管理与分析**
将系统日志(`/var/log/messages`)、应用日志集中存储(如使用 ELK 栈),关注错误信息(`ERROR` 级别)、登录异常(`/var/log/auth.log`)和磁盘错误(`dmesg | grep error`),必要时配置日志告警规则。
6. **磁盘健康监控**
除空间使用率外,需关注磁盘坏块(`smartctl` 工具检测 S.M.A.R.T 信息)和文件系统完整性(定期运行 `fsck`,非挂载状态下),避免硬件故障导致数据丢失。
7. **网络与安全监控**
监控端口开放状态(`netstat`/`ss`)、异常连接(尤其是外部 IP 的高频访问)和防火墙规则生效情况。可结合 `tcpdump` 抓包分析可疑流量。
8. **定期性能基线分析**
记录系统正常运行时的指标基线(如平均负载、内存使用峰值),当指标偏离基线时及时排查,避免微小异常累积成故障。
9. **自动化监控脚本**
对个性化需求(如特定目录文件数、应用响应时间),编写 Shell 或 Python 脚本定期执行检查,输出结果至监控系统或直接触发告警。
10. **监控权限与安全**
限制监控工具的权限(如仅授予读取日志和指标的权限),加密传输监控数据,防止监控系统本身成为安全薄弱点。
通过分层监控(基础指标→服务状态→业务性能)和主动预警,可显著提升系统稳定性和故障响应效率。
网硕互联帮助中心







评论前必须登录!
注册