12Linux之进程管理

12Linux之进程管理

12 进程管理

12.1 进程概念

12.1.1 什么是进程?

  • 程序:存放代码的文件-->静态

    进程:程序的运行过程-->动态(进程是操作系统最核心的概念)

    ​ 操作系统控制着硬件去执行程序的过程

  • 并发:多个任务看起来是同时运行的

    并行:多个任务是真正的同时运行,只有多核才能实现并行

  • 线程:进程内代码的执行过程,一个进程至少有一个线程

    ​ 线程才是CPU的执行单位

    Tips:CPU是运行代码,不是做I/O的

  • 一个进程的多个线程共享该进程的内存资源

    不同进程的多个线程的内存资源互相隔离

  • 提交任务的方式:

    同步:在原地等

    异步:不在原地等

12.1.2 进程状态

  • 进程

    1、正在执行的程序

    2、正在计算机上执行的程序实例

    3、能分配处理器并由处理器执行的实体

    进程的两个基本元素是程序代码和代码相关联的数据集。进程是一种动态描述,但不代表所有的进程都在运行,进程在内存中会有各种状态。

  • 进程状态

    R  # 可执行状态(运行状态)
    S  # 可中断睡眠状态(sleeping)
    D  # 不可中断睡眠(disk sleep)
    T  # 暂停状态
    z  # 僵死状态
    X  # 死亡状态或退出状态(dead)
    
  • 进程状态切换

    # 三种状态
    # 就绪态:进程已分配到除CPU以外的所有必要资源,只要获得处理机便可执行
    # 执行态(Running):进程已获得处理机,其程序正在处理机上执行
    # 阻塞态(Blocked):正在执行的进程,由于等待某个事件发生而无法执行时,就放弃处理机进入阻塞态。例如I/O、申请缓冲区不能满足、等待信号(信件)等
    
    # 状态切换
    就绪->执行
    处在就绪态的进程,当调度器为其分配了处理机后就变成了执行态
    
    执行->就绪
    执行态的进程在其执行过程中,时间片跑完了不得不让出处理机,从执行态变成就绪态
    
    执行->阻塞
    正在执行的进程等待某种事件而无法继续执行时,便从执行态变成阻塞态
    
    阻塞->就绪
    处于阻塞态的进程,等待的事件结束,就从阻塞态变成就绪态
    

12.2 查看进程信息

12.2.1 ps aux

  • 查看进程用户、PID、占用CPU百分比、占用内存百分比、状态、执行的命令等

    -a  # 显示一个终端的所有进程
    -u  # 选择有效的用户ID或用户名
    -x  # 显示没有控制终端的进程,同时显示各个命令的具体路径
    
    [root@ccc ~]# ps aux | head -5
    USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    root          1  0.0  0.3 125356  3792 ?        Ss   14:43   0:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
    root          2  0.0  0.0      0     0 ?        S    14:43   0:00 [kthreadd]
    root          4  0.0  0.0      0     0 ?        S<   14:43   0:00 [kworker/0:0H]
    root          6  0.0  0.0      0     0 ?        S    14:43   0:00 [ksoftirqd/0]
    
    USER 	 # 进行进程的用户
    PID  	 # 进程ID
    %CPU 	 # CPU占用率
    %MEN 	 # 内存占用率
    VSZ   	 # 占用虚拟内存(kb),表示已分配的内存空间大小,不等于实际用到的内存大小
    RSS  	 # 占用实际内存(kb),常驻内存大小,即进程实际占用的物理内存大小
    TTY  	 # 进程运行的终端
    STAT  	 # 进程状态
    START 	 # 进程的启动时间
    TIME	 # 进程占用CPU的总时间
    COMMAND  # 进程文件,进程名。带[]代表内核态进程,不带[]代表用户态进程
    
  • STAT进程状态

    R  # 运行
    S  # 可中断睡眠sleep,即在睡眠的过程中可以接收信号唤醒->执行的I/O操作能得到硬件设备的相应
    D  # 不可中断睡眠,即在睡眠的过程中不可以接收信号唤醒->执行的I/O操作得不到硬件设备的响应
    T  # 停止的进程
    Z  # 僵尸进程
    X  # 死掉的进程(几乎看不见,死掉会被立即回收)
    <  # 优先级较高的进程
    N  # 优先级较低的进程
    s  # 包含子进程
    +  # 是前台的进程组
    l  # 小写字母l代表以线程的方式运行,即多线程
    |  # 多进程
    
  • 两种睡眠状态

    # 1、可中断睡眠状态(S) Interrupt Sleep
    处于这种睡眠状态的进程是可以通过给他发送signal来唤醒的。
    如HUP信号给nginx的master进程,可以让nginx重新加载配置文件而不需要重新启动nginx进程。
    # 2、不可中断睡眠(D) Uninterruptible Sleep
    处于这种状态的进程不接受任何外来的signal
    包括但不限于kill、kill -9、kill -15、ctrl+c、ctrl+z
    
    # 解释
    处于D状态是因为进程长时间等待I/O都没有响应,且被ps看到,意味着可能I/O出现问题或外设本身出现问题或NFS挂载的远程文件系统不可访问。
    只有等待I/O恢复或者重启整个Linux系统才能从D状态恢复。
    
    # 强调
    D不可中断睡眠状态和Z僵尸进程都不可以用kill -9杀死
    

12.2.2 ps -elf

  • 查看ppid

  • ps -ef只打印进程,而ps -elf会打印所有的线程,同时加了两列。

    [root@ccc ~]# ps -ef | head -10
    UID         PID   PPID  C STIME TTY          TIME CMD
    root          1      0  0 14:43 ?        00:00:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
    root          2      0  0 14:43 ?        00:00:00 [kthreadd]
    root          4      2  0 14:43 ?        00:00:00 [kworker/0:0H]
    root          6      2  0 14:43 ?        00:00:00 [ksoftirqd/0]
    root          7      2  0 14:43 ?        00:00:00 [migration/0]
    root          8      2  0 14:43 ?        00:00:00 [rcu_bh]
    root          9      2  0 14:43 ?        00:00:00 [rcu_sched]
    root         10      2  0 14:43 ?        00:00:00 [lru-add-drain]
    root         11      2  0 14:43 ?        00:00:00 [watchdog/0]
    [root@ccc ~]# ps -elf | head -10
    F S UID         PID   PPID  C PRI  NI ADDR SZ WCHAN  STIME TTY          TIME CMD
    4 S root        1     0  0  80   0 - 31339 ep_pol 14:43 ?        00:00:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
    1 S root        2     0  0  80   0 -     0 kthrea 14:43 ?        00:00:00 [kthreadd]
    1 S root        4     2  0  60 -20 -     0 worker 14:43 ?        00:00:00 [kworker/0:0H]
    1 S root        6     2  0  80   0 -     0 smpboo 14:43 ?        00:00:00 [ksoftirqd/0]
    1 S root        7     2  0 -40   - -     0 smpboo 14:43 ?        00:00:00 [migration/0]
    1 S root        8     2  0  80   0 -     0 rcu_gp 14:43 ?        00:00:00 [rcu_bh]
    1 R root        9     2  0  80   0 -     0 -      14:43 ?        00:00:00 [rcu_sched]
    1 S root       10     2  0  60 -20 -     0 rescue 14:43 ?        00:00:00 [lru-add-drain]
    5 S root       11     2  0 -40   - -     0 smpboo 14:43 ?        00:00:00 [watchdog/0]
    

12.2.3 pstree进程树

  • 查看进程树

    [root@ccc ~]# rpm -qf `which pstree`
    psmisc-22.20-16.el7.x86_64
    [root@ccc ~]# pstree
    systemd─┬─NetworkManager───2*[{NetworkManager}]
            ├─VGAuthService
            ├─agetty
            ├─auditd───{auditd}
            ├─chronyd
            ├─crond
            ├─dbus-daemon
            ├─master─┬─pickup
            │        └─qmgr
            ├─nginx───nginx
            ├─polkitd───6*[{polkitd}]
            ├─rsyslogd───2*[{rsyslogd}]
            ├─sshd───sshd───bash───pstree
            ├─systemd-journal
            ├─systemd-logind
            ├─systemd-udevd
            ├─tuned───4*[{tuned}]
            └─vmtoolsd───{vmtoolsd}
    [root@ccc ~]# pstree 4032
    nginx───nginx
    
  • 查看某一个用户的所有进程

    ps -l -u用户

12.2.4 top动态查看

  • 基本用法(-d -p -u)

    [root@ccc ~]# top
    [root@ccc ~]# top -d 1  # 1秒刷新一次,也可top后进界面用s修改
    [root@ccc ~]# top -d 1 -p 进程的PID
    [root@ccc ~]# top -d 1 -p `pgrep nginx`
    [root@ccc ~]# top -d 1 -p `pgrep nginx | head -1`,33  # 查看sshd及PID33的进程
    [root@ccc ~]# top -d 1 -u cjx  # 查看指定用户的进程
    [root@ccc ~]# top -b -n 2 > top.txt  # 将两次top的信息写入文件
    
  • 显示信息解释

    [root@ccc ~]# top
    top - 14:36:59 up 3:38, 2 users, load average: 0.00, 0.01, 0.05
    Tasks: 93 total,  1 running, 92 sleeping,  0 stopped,  0 zombie
    %Cpu(s):0.0 us,0.3 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
    KiB Mem: 995684 total, 633360 free, 119908 used, 242416 buff/cache
    KiB Swap: 1952764 total, 1952764 free,   0 used. 726976 avail Mem 
    
    # 系统整体统计信息部分
    14:36:59 up 3:38  # up左边是当前的时间,右边是运行的时常
    load average: 0.00, 0.01, 0.05  # CPU1分钟、5分钟、15分钟的平均负载
    us  # 用户态进程占用CPU时间的占比
    sy  # 内核态进程占用CPU时间的占比(两者相加最高100)
    ni  # 高优先度进程占CPU时间百分比
    id  # cpu空闲的百分比
    wa  # cpu等待io的百分比
    hi  # 硬件中断,处理硬件中断所占用的时间
    si  # 软件中断,处理软件中断占用的时间
    st  # 被偷走的cpu
    
    # 平均负载
    单位时间内,系统处于可运行状态和不可中断状态的平均进程数(平均活跃进程数)
    # 平均负载相关基础
    核心数为2,平均负载为2,此时cpu刚好被完全占用
    核心数为4,平均负载为2,此时有一半(50%)的CPU是空闲状态
    核心数为1,平均负载为2,此时至少一半的进程抢不到CPU
    
    
    PID  USER   PR  NI    VIRT   RES  SHR S %CPU %MEM   TIME+  COMMAND   
    4861 root   20   0  162092  2204 1556 R  0.3  0.2   0:00.01 top 
       1 root   20   0  125484  3912 2600 S  0.0  0.4   0:01.26 systemd 
       2 root   20   0     0      0     0 S  0.0  0.0   0:00.00  kthreadd
    
    # 进程信息部分
    VIRT  # virtual memory usage虚拟内存
    RES   # resident memory usage常驻内存
    SHR   # shared memory共享内存
    DATA  # 数据占用的内存(可用f空格选中DATA项目q退出)
    
  • 内部命令控制显示方式

    M 	 # 按内存使用降序排序
    P  	 # 根据CPU降序排序
    N 	 # 根据PID降序排序
    R 	 # 反序
    f 	 # 增加显示字段,空格勾选
    1  	 # 显示所有CPU的负载
    s  	 # 更改频率
    z    # 更改颜色
    h/?  # 帮助
    <    # 向前
    >    # 向后
    k    # 给进程发信号,根据PID杀死进程
    
  • 调整进程的优先级

    r  # 调整进程的优先级(Nice Level)
    # 优先级的数值为-20~19
    # 好人值越小优先级越高,越大越低,-20优先级最高,19优先级最低
    # 普通用户只能
    

12.3 管理进程

12.3.1 优先级设置

  • 在启动进程时用nice命令设置优先级

    # 1、命令
    nice [-n 优先级]
    
    # 2、选项介绍
    -n 优先级   # 指定优先级
    --help	   # 帮助信息
    --version  # 版本信息
    
  • 对已运行的进程设置新的优先级

    [root@ccc ~]# renice -20 11111
    

12.3.2 给进程发信号kill

  • kill -l

    [root@ccc ~]# 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	
    
  • 常用选项

    HUP(1)   	 # 1、挂起信号 2、让进程重新加载配置
    KILL(9)  	 # 立即结束程序的运行
    TERM(15)   	 # 终止,是不带参数的kill默认信号,杀死进程
    
    CONT(18) 	 # 被暂停的进程恢复运行
    SIGSTOP(19)  # 暂停进程
    
  • 杀死所有(killall pkill)

    [root@ccc ~]# vim ccc.txt &
    [1] 5108
    [root@ccc ~]# vim ccc.txt &
    [2] 5109
    [1]+  已停止               vim ccc.txt
    [root@ccc ~]# killall -9 vim
    [1]-  已杀死               vim ccc.txt
    [2]+  已杀死               vim ccc.txt
    [root@ccc ~]# vim ccc.txt &
    [1] 5123
    [root@ccc ~]# vim ccc.txt &
    [2] 5124
    [1]+  已停止               vim ccc.txt
    [root@ccc ~]# pkill -9 vim
    [1]-  已杀死               vim ccc.txt
    [2]+  已杀死               vim ccc.txt
    
  • 查看某个用户开启的进程

    [root@ccc ~]# pgrep -l -u cjx
    

12.3.3 HUP信号

  • 在关闭终端时,终端会收到Linux HUP信号(hangup信号),关闭其所有子进程。

  • 想让进程一直在后台运行不受关闭终端的影响,有以下四种方案:

    nohup

    在命令前加上nohup,就会从终端解除进程的关联

    同时在结尾加上&来将命令放入后台运行

    # 1、在终端1输入
    [root@ccc ~]# nohup ping baidu.com &>/dev/null &
    [root@ccc ~]# ps -elf | grep [p]ing  # 查看进程
    4 S root       2034   1979  0  80   0 - 37522 poll_s 15:11 pts/4    00:00:00 ping baidu.com
                
    # 2、关闭终端1
    
    # 3、在终端2查看
    [root@ccc ~]# ps -elf | grep [p]ing  # 查看进程,父进程变为1即systemd进程
    4 S root       2034      1  0  80   0 - 37522 poll_s 15:11 ?        00:00:00 ping baidu.com
    

    setsid

    原理与nohup一致,但setsid直接将进程的父PID设为1,即让运行的进程归属init的子进程

    除非init结束,该子进程才会结束。当前终端结束不会影响进程的运行

    # 1、在终端1执行命令
    [root@ccc ~]# setsid ping baidu.com &>/dev/null &
    [1] 2062
    [root@ccc ~]# ps -elf | grep [p]ing
    4 S root       2063      1  0  80   0 - 37522 poll_s 15:19 ?        00:00:00 ping baidu.com
    [1]+  完成                  setsid ping baidu.com &>/dev/null
    
    # 2、关闭终端1
    
    # 3、在终端2查看
    [root@ccc ~]# ps -elf | grep [p]ing
    4 S root       2063      1  0  80   0 - 37522 poll_s 15:19 ?        00:00:00 ping baidu.com
    

    在子shell中启动进程

    命令加上括号

    # 1、在终端1输入命令
    [root@ccc ~]# (ping vaidu.com &>/dev/null &)
    [root@ccc ~]# ps -elf | grep [p]ing
    4 S root       2103      1  0  80   0 - 37522 poll_s 15:24 pts/4    00:00:00 ping vaidu.com
    
    # 2、关闭终端1
    
    # 3、在终端2查看
    [root@ccc ~]# ps -elf | grep [p]ing
    4 S root       2103      1  0  80   0 - 37522 poll_s 15:24 ?        00:00:00 ping vaidu.com
    

    screen

    让进程运行在新的会话里,从而成为不属于此终端的子进程,关闭终端不会被带走

    # 安装screen
    [root@ccc ~]# yum install screen -y
    
    # 用法1
    # 运行命令
    终端1输入命令
    [root@ccc ~]# screen vim 111.py
    [root@ccc ~]# ps -elf | grep [v]im
    4 S root 2154 2076 0 80 0 - 31934 sys_pa 15:43 pts/6 00:00:00 screen vim 111.py
    5 S root 2155 2154 0 80 0 - 31967 poll_s 15:43 ?     00:00:00 SCREEN vim 111.py
    4 S root 2156 2155 0 80 0 - 37444 poll_s 15:43 pts/2 00:00:00 vim 111.py
                
    关闭终端1
    
    在终端2查看
    [root@ccc ~]# ps -elf | grep [v]im
    5 S root       2155      1  0  80   0 - 31967 poll_s 15:43 ?        00:00:00 SCREEN vim 111.py
    4 S root       2156   2155  0  80   0 - 37444 poll_s 15:43 pts/2    00:00:00 vim 111.py
    
    # 重新连接会话
    [root@ccc ~]# screen -ls
    There are screens on:
    	2155.pts-6.ccc	(Detached)
    	1678.pts-0.ccc	(Attached)
    2 Sockets in /var/run/screen/S-root.
    [root@ccc ~]# screen -r 2155
    
    # 用法2
    # 运行命令
    [root@ccc ~]# screen -S cjx_pm
    # screen会创建一个执行shell的全屏窗口。可执行任意shell程序
    # 输入exit退出该窗口(若该screen窗口唯一,则screen会话结束,否则切换到前一窗口)
    
    # 重新连接会话
    [root@ccc ~]# screen -r cjx_pm
    # 已经指定了名字,可以不用进程ID直接用名字
    
    # 测试
    [root@ccc ~]# screen
    [root@ccc ~]# n=1;while true;do echo $n;sleep 1;((n++));done;
    按下ctrl+a和ctrl+d
    此时整个终端关闭,进程并未结束
    [root@ccc ~]# screen -ls
    There are screens on:
    	2266.pts-4.ccc	(Detached)
    Remove dead screens with 'screen -wipe'.
    1 Sockets in /var/run/screen/S-root.
    [root@ccc ~]# screen -r 2266  # 进程依旧在运行
    
    # 远程演示
    在终端1
    [root@ccc ~]# screen -S cz
    
    在终端2执行的命令,终端1会同步显示
    [root@ccc ~]# screen -x cz
    

12.4 查看网络状态

  • netstat

    [root@ccc ~]# netstat -tunlp
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address       Foreign Address     State    PID/Program name    
    tcp        0      0 0.0.0.0:22          0.0.0.0:*           LISTEN   844/sshd            
    tcp        0      0 127.0.0.1:25        0.0.0.0:*           LISTEN   922/master          
    tcp6       0      0 :::22               :::*                LISTEN   844/sshd            
    tcp6       0      0 ::1:25              :::*                LISTEN   922/master          
    udp        0      0 127.0.0.1:323       0.0.0.0:*                    532/chronyd         
    udp6       0      0 ::1:323             :::*                         532/chronyd       
                            
    -t  # tcp协议
    -u  # udp协议
    -l  # listen
    -p  # PID/Program name
    -n  # 不反解,不将IP地址解析为主机名,不将端口号解析成协议名
    
  • lsof:列出打开文件(lists openfiles)

    默认 : 没有选项,lsof列出活跃进程的所有打开文件
    组合 : 可以将选项组合到一起,如-abc,但要当心哪些选项需要参数
    -a : 结果进行“与”运算(而不是“或”)
    -l : 在输出显示用户ID而不是用户名
    -h : 获得帮助
    -t : 仅获取进程ID
    -U : 获取UNIX套接口地址
    -F : 格式化输出结果,用于其它命令。可以通过多种方式格式化,如-F pcfn(用于进程id、命令名、文件描述符、文件名,并以空终止)
        
    # 1、安装
    [root@ccc ~]# yum install -y lsof
    
    # 2、使用
    # -i显示所有连接
    [root@ccc ~]# lsof -i
    COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    chronyd  532 chrony    5u  IPv4  16273      0t0  UDP localhost:323 
    chronyd  532 chrony    6u  IPv6  16274      0t0  UDP localhost:323 
    sshd     844   root    3u  IPv4  19131      0t0  TCP *:ssh (LISTEN)
    sshd     844   root    4u  IPv6  19140      0t0  TCP *:ssh (LISTEN)
    master   922   root   13u  IPv4  19666      0t0  TCP localhost:smtp (LISTEN)
    master   922   root   14u  IPv6  19667      0t0  TCP localhost:smtp (LISTEN)
    sshd    2182   root    3u  IPv4  47242      0t0  TCP ccc:ssh->192.168.29.2:64066 (ESTABLISHED)
    # -i 6仅获取IPV6流量
    [root@ccc ~]# lsof -i 6
    COMMAND PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    chronyd 532 chrony    6u  IPv6  16274      0t0  UDP localhost:323 
    sshd    844   root    4u  IPv6  19140      0t0  TCP *:ssh (LISTEN)
    master  922   root   14u  IPv6  19667      0t0  TCP localhost:smtp (LISTEN)
    # -i:22仅获取22端口的连接
    [root@ccc ~]# lsof -i:22
    COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    sshd     844 root    3u  IPv4  19131      0t0  TCP *:ssh (LISTEN)
    sshd     844 root    4u  IPv6  19140      0t0  TCP *:ssh (LISTEN)
    sshd    2182 root    3u  IPv4  47242      0t0  TCP ccc:ssh->192.168.29.2:64066 (ESTABLISHED)
    # -i@host显示指定到主机的连接
    # -i@host:port显示基于主机与端口的连接
    # -u 用户 显示指定用户打开了什么
    # -u ^用户 显示除指定用户外其他所有用户做的事
    # kill -9 `lsof -t -u 用户`  消灭指定用户运行的所有东西
    # -c 命令  查看指定的命令正在使用的文件和网络连接
    # -p PID  查看指定进程ID已打开的内容
    # -t  只返回PID
    
  • netstat -an

    [root@ccc ~]# netstat -an 
    [root@ccc ~]# netstat -an | grep :22
    tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
    tcp        0     52 192.168.29.55:22        192.168.29.2:64066      ESTABLISHED
    tcp6       0      0 :::22                   :::*                    LISTEN  
    

12.5 proc文件系统

12.5.1 查看硬盘状态df

  • 显示目录或文件大小du

    [root@ccc ~]# du -sh /root
    96K	/root
    
  • 查看硬盘状态df

    [root@ccc ~]# df -h
    文件系统        容量  已用  可用 已用% 挂载点
    devtmpfs        476M     0  476M    0% /dev
    tmpfs           487M     0  487M    0% /dev/shm
    tmpfs           487M  7.6M  479M    2% /run
    tmpfs           487M     0  487M    0% /sys/fs/cgroup
    /dev/sda3       7.7G  6.3G  1.5G   82% /
    /dev/sda1       473M  123M  351M   26% /boot
    tmpfs            98M     0   98M    0% /run/user/0
    
    [root@ccc ~]# df -T
    文件系统       类型       1K-块    已用    可用 已用% 挂载点
    devtmpfs       devtmpfs  487140       0  487140    0% /dev
    tmpfs          tmpfs     497840       0  497840    0% /dev/shm
    tmpfs          tmpfs     497840    7756  490084    2% /run
    tmpfs          tmpfs     497840       0  497840    0% /sys/fs/cgroup
    /dev/sda3      xfs      8034304 6529180 1505124   82% /
    /dev/sda1      xfs       484004  125552  358452   26% /boot
    tmpfs          tmpfs      99572       0   99572    0% /run/user/0
    

12.5.2 查看内存状态free

  • 内存:/proc/meminfo

    [root@ccc ~]# less /proc/meminfo 
    
  • free

    [root@ccc ~]# free
                  total        used        free      shared  buff/cache   available
    Mem:         995684      148580      454780        7756      392324      655336
    Swap:       1952764           0     1952764
    
    [root@ccc ~]# free -m
                  total        used        free      shared  buff/cache   available
    Mem:            972         145         444           7         383         639
    Swap:          1906           0        1906
    
    [root@ccc ~]# free -wm
                  total        used        free      shared     buffers       cache   available
    Mem:            972         144         444           7           2         381         640
    Swap:          1906           0        1906
    
    # free指当前完全没有被程序使用的内存
    # cache在有需要的时候可以被释放出来供其他进程使用(不是释放所有)
    # available是真正表明系统目前提供给新启动程序的内存
    
  • 释放内存

    [root@ccc ~]# free
                  total        used        free      shared  buff/cache   available
    Mem:         995684      148580      454780        7756      392324      655336
    Swap:       1952764           0     1952764
    [root@ccc ~]# cat /proc/sys/vm/drop_caches 
    0
    [root@ccc ~]# echo 3>/proc/sys/vm/drop_caches
    [root@ccc ~]# free
                  total        used        free      shared  buff/cache   available
    Mem:         995684      148012      453520        7756      394152      655904
    Swap:       1952764           0     1952764
    
  • 内核启动参数

    [root@ccc ~]# cat /proc/cmdline 
    BOOT_IMAGE=/vmlinuz-3.10.0-1127.el7.x86_64 root=UUID=b43c52c4-89a7-48d2-83e4-6e8d35553e64 ro spectre_v2=retpoline rhgb quiet LANG=zh_CN.UTF-8
    [root@ccc ~]# uptime
     17:29:15 up  6:35,  2 users,  load average: 0.00, 0.01, 0.05
    
  • 卸载/proc及重新挂载

    [root@ccc ~]# umount /proc/ -l  # 卸载
    [root@ccc ~]# free -m  # free -m、uptime、lscpu、toop都用不了
    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@ccc ~]# mount -t proc proc /proc/  # 重新挂载
    

12.5.3 查看CPU状态lscpu

  • CPU:/proc/cpuinfo

    [root@ccc ~]# grep "processor" /proc/cpuinfo | wc -l  # 逻辑CPU个数
    1
    [root@ccc ~]# grep "physical id" /proc/cpuinfo | wc -l  # 物理CPU个数
    1
    [root@ccc ~]# grep "cpu cores" /proc/cpuinfo | wc -l  # CPU核数
    1
    [root@ccc ~]# cat /proc/cpuinfo   # 查看cpu信息
    [root@ccc ~]# lscpu
    

12.6 管理后台进程(了解)

  • 了解即可

    [root@ccc ~]# sleep 5000 &  					# 后台运行
    [1] 4487
    [root@ccc ~]# sleep 4000 						# 前台运行
    ^Z												# ctrl+z停止
    [2]+  已停止               sleep 4000
    [root@ccc ~]# jobs								# []编号是作业编号
    [1]-  运行中               sleep 5000 &
    [2]+  已停止               sleep 4000
    [root@ccc ~]# bg %2								# 让作业2在后台运行
    [2]+ sleep 4000 &
    [root@ccc ~]# jobs
    [1]-  运行中               sleep 5000 &
    [2]+  运行中               sleep 4000 &
    [root@ccc ~]# fg %1								# 将作业1调回到前台
    sleep 5000
    ^C												# ctrl+c终止
    [root@ccc ~]# jobs
    [2]+  运行中               sleep 4000 &
    [root@ccc ~]# kill %2							# 杀死作业2
    [root@ccc ~]# jobs
    [2]+  已终止               sleep 4000
    [root@ccc ~]# jobs
    

12.7 管道

12.7.1 管道概念

  • 管道用于进程间的通信
  • 管道操作符号"|"主要用于连接左右两个命令。将左边的命令标准输出,交给右侧命令的标准输入
  • 无法传递标准错误输出至后者命令
  • 格式:cmd1 | cmd2[... | cmdn]

12.7.2 xargs

  • 参数传递,让一些不支持管道的命令可以使用管道技术

    [root@ccc ~]# which cat
    /usr/bin/cat
    [root@ccc ~]# which cat | xargs ls -l
    -rwxr-xr-x. 1 root root 54080 8月  20 2019 /usr/bin/cat
    

12.7.3 实例

  • 统计当前/etc/passwd中用户使用的shell类型

    [root@ccc ~]# awk -F: '{print $7}' /etc/passwd | sort | uniq -c
          4 /bin/bash
          1 /bin/sync
          1 /sbin/halt
         17 /sbin/nologin
          1 /sbin/shutdown
    
  • 打印当前所有的IP

    [root@ccc ~]# ip addr | grep 'inet' | awk '{print $2}' |awk -F"/" '{print $1}'
    127.0.0.1
    ::1
    192.168.29.55
    fe80::20c:29ff:fec0:5db3
    
  • 打印根分区已用空间百分比(仅数字)

    [root@ccc ~]# df -P | grep '/$' |awk '{print $5}' | awk -F"%" '{print $1}'
    82
    

12.7.4 管道中的tee技术

  • -a # 追加

    [root@ccc ~]# ip addr | grep 'inet' | awk '{print $2}' |awk -F"/" '{print $1}' | tee ip.txt
    127.0.0.1
    ::1
    192.168.29.55
    fe80::20c:29ff:fec0:5db3
    [root@ccc ~]# cat ip.txt 
    127.0.0.1
    ::1
    192.168.29.55
    fe80::20c:29ff:fec0:5db3
    
  • 重定向与tee的区别

    [root@ccc ~]# date > date.txt			# 直接将内容写入到date.txt文件中
    [root@ccc ~]# date | tee date.txt		# 执行结果输出至屏幕,且保存至文件
    2020年 11月 05日 星期四 18:57:32 CST
    

12.8 僵尸进程与孤儿进程

12.8.1 僵尸进程

  • 操作系统负责管理进程,应用程序想开子进程都是在像操作系统发送系统调用。

    当子进程死掉以后,操作系统会将子进程占用的重型资源(如内存空间、cpu资源、打开的文件等)

    Linux的机制会保留子进程的进程号、退出状态、运行时间等供父进程查看

    僵尸进程是Linux系统的一种数据结构,所有子进程结束后都会进入僵尸进程的状态

  • 父进程觉得僵尸进程的数据没用以后,由父进程发起一个系统调用wait/waitpid来通知操作系统清理僵尸进程的残余状态

    # 三种情况:
    # 1、Linux系统自带的优秀的开源软件,在开启子进程时,父进程内部都会及时调用wait/waitpid来通知操作系统回收僵尸进程。因此我们通常看不到优秀开源软件堆积僵尸进程,因为及时回收
    
    # 2、水平良好的程序员开发的应用程序,会在父进程内考虑调用wait/waitpid来通知操作系统回收僵尸进程,但发起系统调用时间可能慢一些,可以用命令看到僵尸进程状态
    [root@ccc ~]# ps aux | grep [z]+
    
    # 3、垃圾程序员不知道僵尸进程是什么,操作系统中就会堆积很多僵尸进程,会导致内存充足、硬盘充足、cpu空闲,但新软件无法启动起来的状况。因为僵尸进程会占用大量的PID
    针对情况三,只有杀死父进程,僵尸进程就会由pid为1的顶级进程(init或systend)接手,顶级进程会定期发起系统调用wait/waitpid来通知操作系统清理僵尸进程。
    针对情况二,可以发送信号给父进程,通知他发起系统调用清理僵尸进程
    kill -CHLD 父进程PID
    

12.8.2 孤儿进程

  • 父进程先死掉,而他的一个或多个子进程还在运行,这些子进程就会成为孤儿进程。
  • 孤儿进程会被PID为1的顶级进程接手
  • nohup、setsid原理就类似制造孤儿进程
posted @ 2020-11-19 12:12  drrug  阅读(165)  评论(0编辑  收藏  举报