!!!在开启一天的学习的时候,先做好快照,过程中如果出现意外的报错,解决不了的就立即恢复快照,作为初学者,省时省力,不要过于纠结哪里错了,浪费时间!!!
1.进程介绍
- 程序:没有运行的可执行文件。
- 软件:包含程序、手册、配置文件等全套的东西。软件工程。
- 进程:程序运行后,会使用cpu、内存、磁盘、网络等资源。
- 线程:将程序划分成更小的执行单元。
1.1 进程是什么
进程是已启动的可执行程序的运行中实例。
进程由以下组成部分:
- 已分配内存的地址空间
- 安全属性,包括所有权凭据和特权
- 程序代码的一个或多个执行线程
- 进程状态
进程的环境包括:
- 本地和全局变量
- 当前调度上下文
- 分配的系统资源,如文件描述符和网络端口
1.2 进程产生-fork
# 当前bash中执行sleep,此时的sleep进程就是通过fork产生 # sleep进程是bash进程的子进程 [fengkai@centos7 ~ 19:18:06]$ sleep 51.3 进程状态
补充:操作系统主要职责。
- 任务管理
- 设备管理
- 文件系统
- 内存管理
1.4 查看进程-ps
作用:查看系统中进程信息。
ps 命令选项分为两类:
- 限定查看哪些进程,用来选择进程。
- 对选定的进程查看他们哪些属性。
支持三种版本选项:
- UNIX,使用单个
- - GNU,使用两个
-- - BSD,不使用
-
[fengkai@centos7 ~ 10:38:07]$ 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 7 ? 00:00:00 migration/0 8 ? 00:00:00 rcu_bh 9 ? 00:00:00 rcu_sched 10 ? 00:00:00 lru-add-drain ... ... # PID,进程ID # TTY,进程所在终端 # TIME,进程使用cpu的有效时间,并不是程序的运行时间。 # CMD,进程名称 [fengkai@centos7 ~ 10:39:16]$ ps -ef | head -n 5 UID PID PPID C STIME TTY TIME CMD root 1 0 0 08:31 ? 00:00:02 /usr/lib/systemd/systemd --switched-root --system --deserialize 22 root 2 0 0 08:31 ? 00:00:00 [kthreadd] root 4 2 0 08:31 ? 00:00:00 [kworker/0:0H] root 6 2 0 08:31 ? 00:00:00 [ksoftirqd/0] # UID,进程的执行者 # PPID,进程的父进程ID # C,进程消耗的CPU百分比 # STIME,进程的开始执行的时刻查看特定用户运行的进程
[fengkai@centos7 ~ 10:41:51]$ ps -u fengkai u USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND fengkai 2117 0.0 0.0 161072 2536 ? S 08:32 0:01 sshd: fengkai@ fengkai 2119 0.0 0.0 116448 2952 pts/0 Ss 08:32 0:00 -bash fengkai 2217 0.0 0.0 161072 2556 ? S 08:32 0:00 sshd: fengkai@ fengkai 2220 0.0 0.0 116552 3220 pts/1 Ss 08:32 0:00 -bash fengkai 4211 99.9 0.0 108068 620 pts/1 R 10:28 13:25 md5sum /dev/ze fengkai 4404 0.0 0.0 155448 1860 pts/1 R+ 10:42 0:00 ps -u fengkai ......查看特定终端中进程
[fengkai@centos7 ~ 10:42:04]$ ps -t pts/0 u USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND fengkai 2119 0.0 0.0 116448 2952 pts/0 Ss 08:32 0:00 -bash root 2260 0.0 0.1 232368 4404 pts/0 S 08:32 0:00 su -l root root 2266 0.0 0.0 116540 3376 pts/0 S+ 08:32 0:01 -bash [fengkai@centos7 ~ 10:43:28]$ ps -t pts/1 u USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND fengkai 2220 0.0 0.0 116552 3220 pts/1 Ss 08:32 0:00 -bash fengkai 4211 99.9 0.0 108068 620 pts/1 R 10:28 14:51 md5sum /dev/ze fengkai 4416 0.0 0.0 155448 1868 pts/1 R+ 10:43 0:00 ps -t pts/1 u查看所有进程
[fengkai@centos7 ~ 10:43:51]$ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.1 193824 7000 ? Ss 08:31 0:02 /usr/lib/syste root 2 0.0 0.0 0 0 ? S 08:31 0:00 [kthreadd] root 4 0.0 0.0 0 0 ? S< 08:31 0:00 [kworker/0:0H] root 6 0.0 0.0 0 0 ? S 08:31 0:00 [ksoftirqd/0] ...查看进程树
[fengkai@centos7 ~ 10:44:09]$ ps axf PID TTY STAT TIME COMMAND 2 ? S 0:00 [kthreadd] 4 ? S< 0:00 \_ [kworker/0:0H] ...... 2036 ? Ss 0:00 \_ sshd: fengkai [priv] 2117 ? S 0:01 | \_ sshd: fengkai@pts/0 2119 pts/0 Ss 0:00 | \_ -bash 2260 pts/0 S 0:00 | \_ su -l root 2266 pts/0 S+ 0:01 | \_ -bash 2212 ? Ss 0:00 \_ sshd: fengkai [priv] 2217 ? S 0:00 \_ sshd: fengkai@pts/1 2220 pts/1 Ss 0:00 \_ -bash 4211 pts/1 R 15:42 \_ md5sum /dev/zero 4430 pts/1 R+ 0:00 \_ ps axf ......查看特定进程特定属性
# 通过PID限定 [fengkai@centos7 ~ 10:45:25]$ ps -o pid,%cpu,%mem,cmd 1206 PID %CPU %MEM CMD 1206 0.0 0.1 /usr/sbin/cupsd -f # 通过命令名称限定 [fengkai@centos7 ~ 11:09:46]$ md5sum /dev/zero & # 先执行以上命令 [fengkai@centos7 ~ 11:09:46]$ ps -C md5sum -o pid,%cpu,%mem,cmd PID %CPU %MEM CMD 4211 99.9 0.0 md5sum /dev/zero对进程进行排序,--sort %cpu升序 ,--sort -%cpu降序
[fengkai@centos7 ~ 10:48:36]$ ps axu --sort -%cpu | head USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND fengkai 4211 100 0.0 108068 620 pts/1 R 10:28 20:02 md5sum /dev/zero root 763 0.4 0.1 295564 5292 ? Ssl 08:31 0:34 /usr/bin/vmtoolsd root 1 0.0 0.1 193824 7000 ? Ss 08:31 0:02 /usr/lib/systemd/systemd --switched-root --system --deserialize 22 root 2 0.0 0.0 0 0 ? S 08:31 0:00 [kthreadd] root 4 0.0 0.0 0 0 ? S< 08:31 0:00 [kworker/0:0H] root 6 0.0 0.0 0 0 ? S 08:31 0:00 [ksoftirqd/0] root 7 0.0 0.0 0 0 ? S 08:31 0:00 [migration/0] root 8 0.0 0.0 0 0 ? S 08:31 0:00 [rcu_bh] root 9 0.0 0.0 0 0 ? R 08:31 0:00 [rcu_sched] ......1.5 综合练习
1.解析ps命令左右,用示例说明。
ps用来查看当前活跃的进程,通过一般使用aux或者-ef来查看,单这些内容太多了,多数是使用 ps -o pid,ppid,%cpu,%mem,cmd | head 来定制需要显示的参数
2.控制 jobs
2.1 前台进程和后台进程
作业控制允许单个shell实例运行和管理多个命令。
- 前台进程,一个终端中只有一个前台进程,该进程可以终端窗口中读取输入和响应键盘生成的信号。
- 后台进程,在后台运行的进程,该进程不能从终端读取输入或接收键盘产生的中断。后台进程可能暂停,也可能正在运行。如果正在运行的后台作业尝试从终端读取,它将自动暂停。在ps列表中,tty终端列显示的是?号,那么该进程肯定是后台进程,但并代表显示为其他终端的进程就不是后台进程。
示例:
# 准备脚本 [root@centos7 ~ 11:31:07]# cat << 'EOF' > /usr/local/bin/study > #!/bin/bash > while true > do > echo "$(date): I'm studying [ $@ ]" >> study.log > sleep 1 > done > EOF [root@centos7 ~ 11:31:14]# chmod +x /usr/local/bin/study # 任何一个进程都可以在后台启动,通过增加一个&符号。 # bash会显示job号和进程的PID。shell不需要等待子进程运行结束,而可以继续运行其他命令。 [fengkai@centos7 ~ 11:17:20]$ study Linux & [2] 5115 [fengkai@centos7 ~ 11:32:29]$ jobs [1]- 运行中 md5sum /dev/zero & [2]+ 运行中 study Linux & [fengkai@centos7 ~ 11:32:35]$ fg study Linux ^Z [2]+ 已停止 study Linux [fengkai@centos7 ~ 11:32:59]$ fg %1 md5sum /dev/zero ^Z [1]+ 已停止 md5sum /dev/zero [fengkai@centos7 ~ 11:33:11]$ jobs [1]+ 已停止 md5sum /dev/zero [2]- 已停止 study Linux # 新开窗口动态监控文件study.log内容 [fengkai@centos7 ~ 11:37:29]$ tail -f study.log # 以前台方式运行 [fengkai@centos7 ~ 11:33:18]$ study Python # ctrl+Z 暂停前台进程 ^Z [3]+ 已停止 study Python [laoma@centos7 ~]$ jobs [1]- 运行中 study Linux & [2]+ 已停止 study Python # 将job2和3放到后台运行 [fengkai@centos7 ~ 13:35:30]$ bg %2 [2] study Linux & [fengkai@centos7 ~ 13:39:01]$ bg %3 [3] study Python & [fengkai@centos7 ~ 13:39:03]$ jobs [1] 已停止 md5sum /dev/zero [2] 运行中 study Linux & [3] 运行中 study Python & # 以后台方式运行 [fengkai@centos7 ~ 11:41:18]$ study MySQL & [5] 6609清理实验:
# 前台运行的进程,按ctrl+c终止进程运行 [fengkai@centos7 ~ 13:34:38]$ fg %2 study Linux ^Z [2]+ 已停止 study Linux [fengkai@centos7 ~ 13:34:51]$ fg %3 study Python ^Z [3]+ 已停止 study Python [fengkai@centos7 ~ 13:34:55]$ fg %4 study Linux ^Z [4]+ 已停止 study Linux [fengkai@centos7 ~ 13:34:58]$ fg %5 study MySQL ^Z [5]+ 已停止 study MySQL [fengkai@centos7 ~ 13:35:01]$ jobs [1] 已停止 md5sum /dev/zero [2] 已停止 study Linux [3] 已停止 study Python [4]- 已停止 study Linux [5]+ 已停止 study MySQL==思考:==passwd命令是否在后台运行?
答:需要交互的进程是无法在后台运行的。
[fengkai@centos7 lab 18:36:26]$ passwd & [1] 13036 [fengkai@centos7 lab 18:53:26]$ 更改用户 fengkai 的密码 。 为 fengkai 更改 STRESS 密码。 ^C [1]+ 已停止 passwd思考:如何避免意外断网和关闭终端,导致终端中后台运行的进程终止?
例如:服务器在国外,给服务器打补丁包,打补丁大概需要2个小时。
方法一:nohub commnad &
[fengkai@centos7 lab 18:53:39]$ nohup study Enhlish & [2] 13101 [fengkai@centos7 lab 18:54:27]$ nohup: 忽略输入并把输出追加到"nohup.out" [fengkai@centos7 lab 18:54:29]$方法二:screen
# 先配置epel仓库 [root@centos7 ~ 18:59:04]# curl -s -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo [root@centos7 ~ 18:59:06]# yum install -y screen # 开启一个screen [fengkai@centos7 ~ 18:58:42]$ screen [fengkai@centos7 ~ 18:59:31]$ sleep 1234 # 再启动一个终端,查看screen [fengkai@centos7 ~ 19:00:05]$ screen -ls There is a screen on: 5332.pts-2.centos7 (Attached) 1 Socket in /var/run/screen/S-fengkai. # 此时将执行sleep 1234 的终端关掉 # 再次查看screen [fengkai@centos7 ~ 19:02:27]$ screen -ls There is a screen on: 5332.pts-2.centos7 (Detached) 1 Socket in /var/run/screen/S-fengkai. # 关联到断开的screen [fengkai@centos7 ~ 19:02:53]$ screen -r 5332.pts-2.centos7 # 关闭screen会话 方式1:在screen 会话中执行 exit # 关闭screen会话 方式2:在screen 会话外执行以下命令 # 示例: [fengkai@centos7 ~ 19:03:10]$ screen -X -S 5332.pts-2.centos7 quit # 关闭screen会话 方式3:使用 kill 命令 # 5332.pts-2.centos7中的5332是screen进程的pid [laoma@centos7 ~]$ kill 5332提示:每个用户管理自己的screen会话,root用户也无法看到其他用户screen清单。
3.给进程发信号
3.1 信号介绍
signal 是传递给进程的软中断。
生成信号的事件可以是错误,外部事件或者使用信号发送命令或键盘序列。
3.2 kill 命令
作用:给进程发信号。
# 准备脚本 [root@centos7 ~ 19:24:30]# cat << 'EOF' > /usr/local/bin/study > #!/bin/bash > while true > do > echo "$(date): I'm studying [ $@ ]" >> study.log > sleep 1 > done > EOF [root@centos7 ~ 19:24:33]# chmod +x /usr/local/bin/study # 新开窗口动态监控文件study.log内容 [laoma@centos7 ~]$ tail -f study.log # 创建进程 [fengkai@centos7 ~ 19:24:04]$ study Linux & [1] 5852 [fengkai@centos7 ~ 19:25:22]$ study Python & [2] 5879 # 查看信号清单 [fengkai@centos7 ~ 19:25:35]$ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX # 给job id为1的进程发19信号,暂停运行 [fengkai@centos7 ~ 19:25:54]$ kill -19 %1 [1]+ 已停止 study Linux [fengkai@centos7 ~ 19:26:29]$ jobs [1]+ 已停止 study Linux [2]- 运行中 study Python & # 给job id为1的进程发18信号,继续运行 [fengkai@centos7 ~ 19:26:32]$ kill -18 %1 [fengkai@centos7 ~ 19:27:20]$ jobs [1]+ 运行中 study Linux & [2]- 运行中 study Python & # 给job id为2的进程发SIGTERM信号,终止程序运行,该信号是默认信号 [fengkai@centos7 ~ 19:28:20]$ kill -SIGTERM %2 [fengkai@centos7 ~ 19:28:33]$ jobs [1]+ 运行中 study Linux & [2]- 已终止 study Python [fengkai@centos7 ~ 19:28:36]$ jobs [1]+ 运行中 study Linux & # SIGTERM 信号是默认信号 [fengkai@centos7 ~ 19:28:43]$ kill %1 [fengkai@centos7 ~ 19:29:04]$ jobs [1]+ 已终止 study Linux [fengkai@centos7 ~ 19:29:05]$ jobs # 给PID是10123的进程发默认信号 [fengkai@centos7 ~ 19:29:09]$ study MySQL & [1] 6582 [fengkai@centos7 ~ 19:30:09]$ ps aux|grep study fengkai 6582 0.1 0.0 113284 1448 pts/2 S 19:29 0:00 /bin/bash /usr/local/bin/study MySQL fengkai 6697 0.0 0.0 112824 988 pts/2 S+ 19:30 0:00 grep --color=auto study [fengkai@centos7 ~ 19:30:14]$ kill 6582 [1]+ 已终止 study MySQL [fengkai@centos7 ~ 19:30:55]$ jobs3.3 pkill 和 pgrep 命令
作用:给多个进程发信号。
# 准备 [fengkai@centos7 ~ 19:31:04]$ sleep 1231 & sleep 1232 & sleep 1233 & [1] 6794 [2] 6795 [3] 6796 # 根据进程名查找进程 [fengkai@centos7 ~ 19:32:18]$ pgrep sleep 6793 6794 6795 6796 [fengkai@centos7 ~ 19:32:45]$ pgrep -l sleep 6793 sleep 6794 sleep 6795 sleep 6796 sleep [fengkai@centos7 ~ 19:32:48]$ ps axu|grep sleep fengkai 6794 0.0 0.0 108052 360 pts/2 S 19:32 0:00 sleep 1231 fengkai 6795 0.0 0.0 108052 360 pts/2 S 19:32 0:00 sleep 1232 fengkai 6796 0.0 0.0 108052 360 pts/2 S 19:32 0:00 sleep 1233 root 6810 0.0 0.0 108052 360 ? S 19:32 0:00 sleep 60 fengkai 6814 0.0 0.0 112824 988 pts/2 S+ 19:33 0:00 grep --color=auto sleep # 给sleep相关进程发默认信号 [fengkai@centos7 ~ 19:33:17]$ pkill sleep pkill: killing pid 6810 failed: 不允许的操作 [1] 已终止 sleep 1231 [2]- 已终止 sleep 1232 [3]+ 已终止 sleep 1233 [fengkai@centos7 ~ 19:33:42]$ ps axu|grep sleep root 6824 0.0 0.0 108052 360 ? S 19:33 0:00 sleep 60 fengkai 6826 0.0 0.0 112824 984 pts/2 S+ 19:33 0:00 grep --color=auto sleep # 根据用户名匹配程序 [fengkai@centos7 ~ 19:33:54]$ ps -u fengkai PID TTY TIME CMD 2162 ? 00:00:00 sshd 2165 pts/0 00:00:00 bash 4648 ? 00:00:00 sshd 4653 pts/1 00:00:00 bash 5215 ? 00:00:00 sshd 5218 pts/3 00:00:00 bash 5733 ? 00:00:00 sshd 5738 pts/2 00:00:00 bash 6827 pts/2 00:00:00 ps [fengkai@centos7 ~ 19:34:23]$ pgrep -u fengkai 2162 2165 4648 4653 5215 5218 5733 5738 # kill相应用户所有进程,也就是注销用户 [root@centos7 ~ 19:24:56]# pkill -u fengkai # 根据终端匹配 [fengkai@centos7 ~ 19:35:30]$ sleep 1231 & sleep 1232 & [1] 6957 [2] 6958 [fengkai@centos7 ~ 19:35:36]$ tty /dev/pts/1 [fengkai@centos7 ~ 19:35:40]$ pgrep -t pts/1 -l 6918 bash 6957 sleep 6958 sleep [fengkai@centos7 ~ 19:36:06]$ pkill -t pts/1 [1]- 已终止 sleep 1231 [2]+ 已终止 sleep 1232 # 给bash发默认信号,bash进程屏蔽了 [fengkai@centos7 ~ 19:36:22]$ pkill 6918 # 根据PPID,给子进程发信号 [fengkai@centos7 ~ 19:37:16]$ sleep 1231 & sleep 1232 & [1] 7214 [2] 7215 [fengkai@centos7 ~ 19:37:31]$ ps jf PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 6913 6918 6918 6918 pts/1 7217 Ss 1000 0:00 -bash 6918 7214 7214 6918 pts/1 7217 S 1000 0:00 \_ sleep 1231 6918 7215 7215 6918 pts/1 7217 S 1000 0:00 \_ sleep 1232 6918 7217 7217 6918 pts/1 7217 R+ 1000 0:00 \_ ps jf 6861 6865 6865 6865 pts/0 6865 Ss+ 1000 0:00 -bash [fengkai@centos7 ~ 19:37:39]$ pkill -P 6918 [1]- 已终止 sleep 1231 [2]+ 已终止 sleep 1232如果pgrep无法过滤出具有特定特征的进程,使用ps和kill配合完成。
# 环境准备 # 暂停 yum 安装进程 [root@centos7 ~ 19:39:28]# yum install httpd # 按ctrl+Z 已加载插件:fastestmirror, langpacks Loading mirror speeds from cached hostfile * base: mirrors.cloud.aliyuncs.com * extras: mirrors.cloud.aliyuncs.com * updates: mirrors.cloud.aliyuncs.com 正在解决依赖关系 --> 正在检查事务 ---> 软件包 httpd.x86_64.0.2.4.6-99.el7.centos.1 将被 安装 --> 正在处理依赖关系 httpd-tools = 2.4.6-99.el7.centos.1,它被软件包 httpd-2.4.6-99.el7.centos.1.x86_64 需要 ^Z [1]+ 已停止 yum install httpd [root@centos7 ~ 19:39:46]# ps aux|grep yum root 7285 4.4 1.4 1018684 56984 pts/0 T 19:39 0:00 /usr/bin/python /bin/yum install httpd root 7327 0.0 0.0 112824 984 pts/0 S+ 19:40 0:00 grep --color=auto yum [root@centos7 ~ 19:40:03]# ps axu | grep yum |grep -v grep | awk '{print $2}' 7285 [root@centos7 ~ 19:41:25]# kill -9 $(ps axu | grep yum |grep -v grep | awk '{print $2}') [root@centos7 ~ 19:41:42]# [1]- 已杀死 yum install httpd [2]+ 已杀死 yum install httpd # 或者 [root@centos7 ~ 19:42:07]# pkill -9 yum [root@centos7 ~ 19:42:13]# [1]+ 已杀死 yum install httpd # 或者 [root@centos7 ~ 19:42:22]# kill -9 $(pgrep yum) [root@centos7 ~ 19:42:26]# jobs [1]+ 已杀死 yum install httpd3.4 whoami-who-w-last 命令
# 当前系统登录的用户 [fengkai@centos7 ~ 19:39:20]$ whoami fengkai # 当前系统登录的用户详细信息 [fengkai@centos7 ~ 19:43:24]$ who fengkai pts/0 2026-07-21 19:35 (10.1.8.1) fengkai pts/1 2026-07-21 19:35 (10.1.8.1) # 当前系统登录的用户详细信息 [fengkai@centos7 ~ 19:43:27]$ w 19:43:28 up 2:49, 2 users, load average: 0.07, 0.03, 0.05 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT fengkai pts/0 10.1.8.1 19:35 48.00s 0.10s 0.19s sshd: fengkai [priv] fengkai pts/1 10.1.8.1 19:35 0.00s 0.08s 0.00s w # 系统中用户登录记录 [fengkai@centos7 ~ 19:43:28]$ last fengkai pts/1 10.1.8.1 Tue Jul 21 19:35 still logged in fengkai pts/0 10.1.8.1 Tue Jul 21 19:35 still logged in fengkai pts/2 10.1.8.1 Tue Jul 21 19:24 - 19:35 (00:11) fengkai pts/4 :pts/3:S.0 Tue Jul 21 19:03 - 19:05 (00:01) fengkai pts/4 :pts/2:S.0 Tue Jul 21 18:59 - 19:02 (00:03) fengkai pts/3 10.1.8.1 Tue Jul 21 18:58 - 19:35 (00:36) ... ... fengkai pts/1 10.1.8.1 Tue Jul 14 10:43 - 11:34 (00:50) fengkai pts/0 :0 Tue Jul 14 10:41 - 11:12 (00:30) fengkai :0 :0 Tue Jul 14 10:39 - 11:12 (00:32) reboot system boot 3.10.0-1160.71.1 Tue Jul 14 10:37 - 11:34 (00:56) wtmp begins Tue Jul 14 10:37:40 20263.5 案例:kill 不掉的进程
一个进程杀掉之后,又出现了。怎么让这个程序永久 kill 掉?
模拟:
# 准备程序 [fengkai@centos7 ~ 19:43:59]$ mkdir bin [fengkai@centos7 ~ 19:45:57]$ cat > bin/mm <<EOF > #!/bin/bash > while true > do > md5sum /dev/zero > sleep 1 > done > EOF [fengkai@centos7 ~ 19:46:05]$ chmod +x bin/mm [fengkai@centos7 ~ 19:46:13]$ # 执行程序 [fengkai@centos7 ~ 19:46:13]$ nohup mm & [1] 7427 [fengkai@centos7 ~ 19:46:31]$ nohup: 忽略输入并把输出追加到"nohup.out" [fengkai@centos7 ~ 19:46:32]$处理过程
# 查找进程 [fengkai@centos7 ~ 19:46:32]$ ps axo pid,%cpu,command --sort -%cpu|head -n 5 PID %CPU COMMAND 7428 99.4 md5sum /dev/zero 764 0.5 /usr/bin/vmtoolsd 1922 0.1 /usr/bin/gnome-shell 7216 0.1 [kworker/0:3] # kill 进程,再次查看,换了个PID,程序还在 [fengkai@centos7 ~ 19:47:39]$ kill 7428 [fengkai@centos7 ~ 19:48:15]$ ps axo pid,%cpu,command --sort -%cpu|head -n 5 PID %CPU COMMAND 7448 103 md5sum /dev/zero 764 0.5 /usr/bin/vmtoolsd 1922 0.1 /usr/bin/gnome-shell 7216 0.1 [kworker/0:3] # 思路一:把 md5sum 程序删除,使用 mv 模拟 [root@centos7 ~ 19:45:33]# mv /bin/md5sum ./md5sum [fengkai@centos7 ~ 19:49:36]$ kill 7448 [fengkai@centos7 ~ 19:49:49]$ ps axo pid,%cpu,command --sort -%cpu|head -n 5 PID %CPU COMMAND 764 0.5 /usr/bin/vmtoolsd 1922 0.1 /usr/bin/gnome-shell 1 0.0 /usr/lib/systemd/systemd --switched-root --system --deserialize 22 2 0.0 [kthreadd] # 移回去 [root@centos7 ~ 19:49:27]# mv ./md5sum /bin/md5sum [fengkai@centos7 ~ 19:49:50]$ ps axo pid,%cpu,command --sort -%cpu|head -n 5 PID %CPU COMMAND 7614 99.5 md5sum /dev/zero 764 0.5 /usr/bin/vmtoolsd 1922 0.1 /usr/bin/gnome-shell 1 0.0 /usr/lib/systemd/systemd --switched-root --system --deserialize 22 # 思路二:找到幕后推手,也就是找到父进程 [fengkai@centos7 ~ 19:51:04]$ ps ax -f|grep -e md5sum -e PPID UID PID PPID C STIME TTY STAT TIME CMD fengkai 7614 7427 99 19:50 pts/1 R 0:54 md5sum /dev/zero fengkai 7628 6918 0 19:51 pts/1 S+ 0:00 grep --color=auto -e md5sum -e PPID [fengkai@centos7 ~ 19:51:37]$ kill 7614 7427 [fengkai@centos7 ~ 19:52:28]$ ps axo pid,%cpu,command --sort -%cpu|head -n 5 PID %CPU COMMAND 764 0.5 /usr/bin/vmtoolsd 1922 0.1 /usr/bin/gnome-shell 1 0.0 /usr/lib/systemd/systemd --switched-root --system --deserialize 22 2 0.0 [kthreadd] [1]+ 已终止 nohup mm4. 特殊进程(自学)
4.1 僵尸进程
4.1.1僵尸进程介绍
如果一个进程退出了,立马X状态,作为父进程没有机会拿到子进程的退出结果。所以在Linux中,一般进程不会立即退出,而是要维持一个状态叫做Z,也叫做僵尸状态,方便后续父进程读取该子进程的退出结果。
僵尸状态会以终止状态保持在进程列表中,并且会一直等待父进程读取退出状态码。所以只要子进程退出,父进程还在运行,但是父进程没有读取子进程状态,子进程就进入Z状态。
4.1.2僵尸进程模拟
可以使用实验来模拟僵尸状态: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。
4.1.3僵尸进程危害
进程的退出状态必须被维持下去,因为它要告诉它的父进程,你交给我的任务,我办的怎么样了,可是父进程一直不读取,那么进程就处于Z状态。
维护退出状态本身就是使用数据维护,属于进程的基本信息,所以要保存在tast_struct(PCB)中,Z状态一直不退出,PCB就需要一直维护。
那么,一个父进程创建了很多子进程,但是不回收,就会造成资源的浪费,因为数据结构对象本身就要占用内存,就比如C语言中定义一个结构体变量,就需要在内存的某个位置进行开辟空间。
太多的僵尸进程会造成PID资源浪费,无法创建新的进程,因为一个操作系统的进程总数是有上限。
4.2 孤儿进程
4.2.1孤儿进程介绍
父进程如果提前退出,子进程后退出,子进程就称为孤儿进程。子进程退出后处于Z状态,系统如何处理?
此时,子进程被1号进程systemd领养,由systemd回收。
4.2.2孤儿进程模拟
写一段代码,让子进程运行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了。
4.3.3孤儿进程危害
虽然孤儿进程由systemd直接管理了,但如果仍然不停产生新的孤儿进程则会导致占用过多系统资源。需要开发人员检查代码,避免这个问题。如果孤儿进程没有实际意义,则可以通过kill或pkill终止。