25.linux上HUP信号$僵尸进程与孤儿进程的区别

1|0一.关于HUP信号

1|11.什么是HUP信号

  • hup信号除了在上一篇讲的从新加载配置文件功能外还具有另外一种功能

  • 当用户注销(exit, logout, Ctrl + d),或者网络断开时,终端会收到Linux HUP 信号

  • HUP信号会使其关闭所有子进程, 这样就会关闭你不想关闭的进程

  • 解决方法:

       1.让进程忽略Linux HUP信号
        2.让进程运行在新的终端里,从而不属于当前终端

1|22.nohup命令

  • nohup 顾名思义,就是忽略 hup 信号
  • nohup 通常与 & 符号连用, 让提交的命令忽略 Linux HUP 信号
  • 用法
    🌵nohup使用十分方便,只需在要处理的命令前加上"nohup"即可,一般配合"&"符号将其放入后台
                # nohup [命令] &
  • 示例
   
  🌵在终端 a 使用"nohup"运行一条"ping"命令
                [root@shawn ~]# nohup ping baidu.com &> /dev/null &
   
  🌵在终端 b 过滤出"ping"进程的信息
                [root@shawn ~]# ps -elf | grep [p]ing
                4 S root 57838 57801 0 80 0 - 37522 poll_s 19:10 pts/1 00:00:00 ping baidu.com
 
  🌵我们"kill"掉该进程的父进程"57801"(终端 a),并再次查看
                [root@shawn ~]# kill -9 57801
                [root@shawn ~]# ps -elf | grep [p]ing
                 4 S root 57838 1 0 80 0 - 37522 poll_s 19:10 pts/1 00:00:00 ping baidu.com
 
  🌵可以发现终端 a 关闭后,其下的子进程并没有关闭,但父进程PID变成了"1",即"systemd"进程

1|33.setsid命令

  • 原理与 nohup 一样
  • setsid 是直接将进程的父进程PID设置成 1
  • 即直接让 systemd 成为该进程的父进程, 那么除非 systemd 结束,该子进程才会结束
  • 用法
             # setsid [命令] ( & 符号可加可不加)
  • 示例
         🌵在终端 a 中使用"setsid"命令运行一条"sleep"命令
                [root@shawn ~]#setsid sleep 200000
         🌵关闭终端 a, 在终端 B 中查看进程信息,发现进程还在运行,并且父进程PID为 "1"
                [root@shawn ~]#ps -elf | grep [s]leep
                   0 S root 63319 1 0 80 0 - 27013 hrtime 20:56 ? 00:00:00 sleep 100000

1|44.在子shell中提交任务

  • 什么是子 Shell
              就是从当前的的"shell"环境中开的一个新"shell"
  • 用法
             # ([命令] &)
          🌵圆括号结构能够强制将其中的命令运行在子Shell中
  • 示例
           🌵在终端 a 中使用"( )"结构运行一条"ping"命令
               [root@shawn ~]#(ping baidu.com&>/dev/null &)
 
           🌵关闭终端 a, 在终端 B 中查看进程信息,发现进程还在运行,并且父进程PID为 "1"
                [root@shawn ~]#ps -elf | grep [p]ing
                 4 S root 64003 1 0 80 0 - 37522 poll_s 21:09 pts/1 00:00:00 ping baidu.com

1|55.screen命令

  • 什么是screen
                Screen 是一个命令行终端切换的软件
                在"screen"环境下,所有的会话都将独立运行
                使用前先安装它"yum install screen -y"
  • 用法
                # screen [后面接一些命令或用法,不唯一,往下会演示]
  • 常用命令选项
-ls显示现有的screen会话,格式为(pid.tty.host)
-r [name/PID] 恢复一个screen会话
-S [name] 创建一个screen会话并命名
-x 共享一个会话演示,可以操作(多个屏幕)
-wipe 先检查所有screen会话, 然后删除无法使用screen会话
Ctrl + d / exit 退出screen会话
Ctrl + a,Ctrl + d 隐藏当前screen会话窗口,切到上一个窗口/终端
  • screen运行机制

           使用 screen 运行一个 vim

      screen vim nnn.txt然后查看进程信息

           可以发现一共产生了这三个进程, 画个图👇👇👇👇👇

        我们将screen这个进程 kill掉看看结果

        发现对 vim 进程真的没有影响, 而 SCREEN 也被 systemd 接管了

     这不就是我们使用 screen 想要的结果吗

  • 示例
          🌵开启一个窗口并指定名字,也可以不指定
               # screen -S song1
          🌵在screen会话窗口中的退出操作
                [root@shawn ~]#logout bash: logout: 不是登录shell: 使用 `exit' #所以这种退出方式不可用
                  1."Ctrl + d" 以及 "# exit" 可用
                  2."Ctrl + a" 紧接着 "Ctrl + d" 可以将这个会话放在后台,并切回到前一个窗口/终端(注意并不是关闭)
         🌵显示所有的screen会话,就是列出你创建的screen会话(里面可能会有一些无法使用的会话)
                # screen -ls
                  "kill"命令通过进程号杀掉一个"screen"会话, 这种无效会话会在"screen -ls"中显示出来
         🌵清除掉"kill"杀掉的无效会话
               # screen -wipe
                     这个命令运行完后,无效的会话后面会出现(Remove),然后就被清除掉了
         🌵恢复之前放在后台(或者是隐藏)的screen会话窗口
                # screen -r song1
         🌵共享一个screen会话屏幕
                # screen -x song1
                     在不同的终端里面都可以通过 "-x" 后面接名字链接到这个screen会话窗口,并进行操作
         🌵使用"screen"执行一个"vim nnn.txt"操作
                # screen vim nnn.txt
                    执行后直接就是以一个新的窗口打开"vim"进入到命令模式,退出"vim"将退出该窗口/会话

2|0二.孤儿进程

2|11.什么是孤儿进程

  • 当一个父进程创建了多个子进程, 子进程再创建子子进程等等
  • 父进程因正常运行完毕或其他情况被干掉的时候, 它的子进程就变成了孤儿进程
  • 为了避免孤儿进程完成任务后没有父亲通知操作系统回收资源
  • 于是 PID 为 "1"的顶级进程 systemd 就接手了这个孤儿进程
  • systemd 相当于一个孤儿院, 但凡是孤儿进程都会成为它的子进程

2|22.孤儿进程演示

  • 先在一个虚拟终端里开启一个 Bash 进程,把他当做父进程
  • 紧接着开启一个 "sleep 1000 &" 进程, 把它当做子进程
  • 然后在另一个虚拟终端查看这两个进程信息

  • 再杀掉 sleep 的父进程 Bash 看看结果如何

  • 图示

3|0三.僵尸进程

3|11.什么是僵尸进程

  • 这是Linux出于好心的设计

  • 一个父进程开启了一堆子进程, 当子进程比父进程先运行完(死掉)

  • 操作系统会释放子进程占用的重型资源(内存空间, CPU资源, 打开的文件)

  • 但会保留子进程的关键信息(PID, 退出状态, 运行时间等)

  • 目的是为了让父进程能随时查看自己的子进程信息(不管该子进程有没有死掉)

  • 这种已经死掉的子进程都会进入僵尸状态, ''僵尸进程''是Linux系统的一种数据结构

3|22.僵尸进程回收----概念

  • 操作系统保留子进程信息供父进程查看
  • 当父进程觉得不再需要查看的时候, 会向操作系统发送一个 wait / waitpid 系统调用
  • 于是操作系统再次清理僵尸进程的残余信息

3|33.僵尸进程回收----实际

  • 优秀的开源软件
                  这些软件在开启子进程时, 父进程内部会及时调用"wait" / "waitpid" 通知操作系统来回收僵尸进程
  • 水平良好的开发者
                 功底深厚,知道父进程要对子进程负责
                 会在父进程内部考虑到调用 "wait" / "waitpid" 通知操作系统回收僵尸进程
                 但是发起系统调用时间可能慢了一点
                 于是我们就可以使用 "ps aux | grep [z]+" 命令查看到僵尸进程
  • 水平非常低的开发者
                 技术半吊子,只知道开子进程,父进程也不结束,并在那一直开子进程,不知道什么是僵尸进程
                 系统调用 "wait" / "waitpid" 也没有听说过
                 于是计算机会堆积许多的僵尸进程,占用着大量的"pid",(每启动一个进程就会分配一个"pid号")
                 计算机进入一个奇怪的现象: 内存够用,硬盘充足,CPU空闲,但新的程序无法启动
                 这就是因为"PID"不够用了

3|44.如何清理僵尸进程

  • 针对良好的开发者
                我们可以手动发信号给父进程: "# kill -CHLD [父进程的PID]"
                通知父进程快点向操作系统发起系统调用 "wait" / "waitpid" 来清理变成僵尸的儿子们
  • 针对半吊子水平的开发者
               这种情况子下,我们只能将父进程终结,因为你发给它的信号不会得到回应
               父进程被杀死,"僵尸进程"将会变成"僵尸孤儿进程"
               但凡是"孤儿进程"都会被Linux系统中"PID"为"1"的顶级进程"systemd"回收
               "systemd"会发起系统调用 "wait" / "waitpid" 来通知操作系统清理僵尸进程
                   # Centos7 的顶级进程为 systemd
                   # Centos6 的顶级进程为 init

4|0四.查看网络状态

4|11.命令

  netstat

4|22.选项

-ttcp协议
-u udp协议
-l listen
-p PID/Program name
-n 不反解,不将IP地址解析为主机号,不将端口号解析成协议名

4|33.示例

  🌵过滤出 22 号端口
           [root@shawn home]#netstat -an | grep :22
                        tcp       0     0       0.0.0.0:22                  0.0.0.0:*                            LISTEN
                        tcp       0    52      192.168.12.178:22   192.168.12.179:57156     ESTABLISHED
                        tcp6     0     0        :::22
 
 🌵过滤出 25 号端口
              [root@shawn home]#netstat -an | grep :25
                          tcp        0          0        127.0.0.1:25 0.0.0.0:*    LISTEN
                          tcp6      0          0         ::1:25 :::*                       LISTEN
 
 
🌵查看你进程开打的文件,打开文件的进程,进程打开的端口(TCP、UDP)(了解)
              [root@shawn home]#lsof -i:22
                  COMMAND     PID      USER    FD    TYPE   DEVICE   SIZE/OFF    NODE NAME
                  sshd                1201     root        3u     IPv4    20467        0t0              TCP *:ssh (LISTEN)
                  sshd -              1201     root        4u     IPv6    20476        0t0              TCP *:ssh (LISTEN)
                   sshd               1289      root       3u     IPv4    21134         0t0               TCP shawn:ssh->192.168.12.179:57156 (ESTABLISHED)

5|0五.proc 文件系统

 

5|11.什么是 proc 文件系统

  • proc文件系统是一个虚拟文件系统,它只存在内存当中,而不占用外存空间
               它以文件系统的方式为访问系统内核数据的操作提供接口
               用户和应用程序可以通过proc得到系统的信息,并可以改变内核的某些参数
               由于系统的信息,如进程,是动态改变的
               所以用户或应用程序读取proc文件时
               proc文件系统是动态从系统内核读出所需信息并提交的

5|22.查看CPU信息

  •  CPU信息文件: /proc/cpuinfo
             🌵可以用文件查看命令查看(more,less,cat.....)
                  [root@shawn ~]#less /proc/meminfo
             
            🌵过滤查看逻辑"CPU"个数
                   [root@shawn ~]#grep "processor" /proc/cpuinfo
                           processor : 0
   
            🌵过滤查看物理"CPU"个数
                   [root@shawn ~]#grep "physical id" !$
                           grep "physical id" /proc/cpuinfo
                           physical   id : 0
 
            🌵"cpu"核数
                     [root@shawn ~]#grep "cpu cores" !$
                            grep "cpu cores" /proc/cpuinfo
                             cpu  cores : 1

5|33.查看内存信息

  • 内存信息文件: /proc/meminfo
            🌵可以用文件查看命令查看(more,less,cat.....)
                       [root@shawn ~]#less /proc/meminfo
                       [root@shawn ~]#lscpu
         
           🌵查看内存使用情况(单位:b,k,m,g)(buffer/cache分开查看)
                       [root@shawn ~]#free
                           total         used        free           shared     buff/cache     available
                Mem: 995684    125424    544644      6984        325616          714228
                Swap: 2464760  776         2463984
                       
                        [root@shawn ~]#free -m
                               total      used      free          shared         buff/cache     available
                   Mem:    972       114        805           6                  53                  758
                   Swap:  2406        0         2406
                         [root@shawn ~]#free -wm
                               total     used          free       shared     buffers     cache     available
                   Mem:   972     114             805        6              0             53          758
                   Swap: 2406     0               2406
 
              🌵将"buff"缓冲区内容写入硬盘(通常多敲几遍)
                         [root@shawn ~]#sync
                         [root@shawn ~]#sync
 
            🌵释放"buff/cache"空间
                          [root@shawn ~]#free
                       total         used            free          shared          buff/cache      available
            Mem:  995684    125424       544644   6984             325616         714228
           Swap:  2464760   776            2463984
                           [root@shawn ~]#echo 3 > /proc/sys/vm/drop_caches
                           [root@shawn ~]#free
                        total           used           free            shared           buff/cache   available
            Mem:   995684     112056        845300       6988             38328          789576
            Swap:  2464760    776             2463984
 
             🌵使用"echo > 3"将"buff/cache"的内存空间释放,前后对比可发现"free"变大了

5|44.内核启动参数

  • 文件:/proc/cmdline
              🌵可以用文件查看命令查看(more,less,cat.....)
                      [root@shawn ~]#less /proc/cmdline
                         BOOT_IMAGE=/vmlinuz-3.10.0-1127.19.1.el7.x86_64 root=UUID=74cf4c48-4939-4398-a99a-65fb8e830a8d ro rhgb quiet net.ifnames=32 biosdevname=32 LANG=zh_CN.UTF-8
             
             🌵显示"uptime",显示结果与"top"命令显示的首行一样
                      [root@shawn ~]#uptime 16:43:57 up 4:26, 1 user, load average: 0.00, 0.01, 0.05

5|55.卸载与挂载 /proc

  • 卸载
            🌵一般需要使用"-l"强制卸载
                      [root@shawn ~]#umount /proc
                         umount: /proc:目标忙。
                         (有些情况下通过 lsof(8) 或 fuser(1) 可以 找到有关使用该设备的进程的有用信息)
                      [root@shawn ~]#umount /proc -l
           
             🌵卸载后以下命令不可用 "free", "uptime", "lscpu", "toop"
                     [root@shawn ~]#free Error: /proc must be mounted   #表示命令不可用了
                          To mount /proc at boot you need an /etc/fstab line like:
                             proc      /proc      proc      defaults
                             In the meantime, run "mount proc /proc -t proc"
                      [root@shawn ~]#uptime Error: /proc must be mounted
                          To mount /proc at boot you need an /etc/fstab line like:
                              proc    /proc        proc       defaults
                              In the meantime, run "mount proc /proc -t proc"
                               .............
                               ........
                               ...
  • 重新挂载
             🌵重新挂载后命令可用
                     [root@shawn ~]#mount -t proc proc /proc
                     [root@shawn ~]#free
                             total          used          free            shared          buff/cache     available
                Mem:    995684    117704     814036        6992             63944             771124
                Swap:  2464760    776          2463984
                      "-t proc" : 指定文件系统类型
                      "proc" : 文件系统, 虚拟文件系统
                       "/proc" : 挂载点
               
                 # du -sh * 查看当前目录下各个文件及目录占用空间大小
                 # du -sh [目录] 查看目录目录下各个文件及目录占用空间大小

6|0六.管理后台进程

6|1   1.jobs显示当前终端里的后台任务

6|2   2.bg让作业在后台运行

6|3   3.fg将作业调回前台

6|4   4.示例

         🌵首先开启三个任务,"[ ]"里面的是作业编号
                [root@shawn home]#sleep 5000 & [4] 5300
                [root@shawn home]#sleep 4000 & [5] 5301
                [root@shawn home]#sleep 3000 & [6] 5302
         🌵使用"jobs"命令查看当前终端后台任务(其他终端看不到)
                 [root@shawn home]#jobs
                    [4] 运行中 sleep 5000 &
                    [5]- 运行中 sleep 4000 &
                    [6]+ 运行中 sleep 3000 &
          🌵使用"fg"命令将作业"4"调回前台运行, 然后"Ctrl + z"将其暂停并挂起后台
                   [root@shawn home]#fg %4 
                        sleep 5000
                        ^Z                     #这里是"Ctrl + z"
                       [4]+ 已停止        sleep 5000
                   [root@shawn home]#jobs
。                     [4]+ 已停止       sleep 5000                #可以发现已经停止了
                         [5] 运行中         sleep 4000 &
                         [6]- 运行中       sleep 3000 &
          🌵使用"bg"将作业"4"运行在后台
                    [root@shawn home]#bg %4
                          [4]+                  sleep 5000 &
                    [root@shawn home]#jobs
                          [4] 运行中            sleep 5000 &           #可以发现已经在后台运行了
                          [5]- 运行中           sleep 4000 &
                          [6]+ 运行中          sleep 3000 &
            🌵使用"kill"命令杀掉作业
                    [root@shawn home]#kill %4
                    [root@shawn home]#jobs
                           [4] 已终止            sleep 5000                 #可以看到作业已经终止
                           [5]- 运行中           sleep 4000 &
                           [6]+ 运行中           sleep 3000 &

7|0七.管道

7|11.什么是管道

  • 主要用来连接左右两个命令, 符号 "|"

  • 将左侧命令的标准输出, 传给右侧命令的标准输入

  • 注意: 无法传递标准错误输出至后者命令

  • 用法:command1 | command2 | command3 ......

7|22.管道示意图

  • 示例
             🌵过滤网卡init
                   [root@shawn ~]#ifconfig | grep "inet"
                        inet 192.168.12.178 netmask 255.255.255.0 broadcast 192.168.12.255
                        inet6 fe80::20c:29ff:fe3e:456a prefixlen 64 scopeid 0x20<link>
                         inet 127.0.0.1 netmask 255.0.0.0
                         inet6 ::1 prefixlen 128 scopeid 0x10<host>
                  [root@shawn ~]#ifconfig | grep "inet" | awk '{print $2}'
                          192.168.12.178
                          fe80::20c:29ff:fe3e:456a
                          127.0.0.1
                           ::1

7|33.管道中的 tee 技术

  • 示意图

  • 示例

7|44.xargs 参数传递

  • 让不支持管道的命令也可以使用管道内的内容
                find /root -name "song*" | xargs rm -rvf                    #删除管道里的内容
                find /root -name "song*" | xargs -I {} cp -rf {} /tmp
                find /root -name "song*" | xargs -I {} mv {} /tmp
                find /root -name "song*" | xargs -I {} chmod 777 {}   #修改找到的文件的权限等级

__EOF__

本文作者ଲ小何才露煎煎饺
本文链接https://www.cnblogs.com/zeny/articles/14443969.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   ଲ小何才露煎煎饺  阅读(296)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
点击右上角即可分享
微信分享提示