• Linux进程管理(一)


    Linux进程管理(一)

    @

    进程基本概述

    进程是已启动的可执行程序的运行中实例。

    /proc目录下以数字为名的目录,每一个目录代表一个进程,保存着进程的属性信息。每一个进程的PID是唯一的,就算进程退出了,其它进程也不会占用其PID。

    进程的组成部分

    已分配内存的地址空间
    安全属性,包括所有权凭据和特权
    程序代码的一个或多个执行线程
    进程状态

    进程的环境

    本地和全局变量
    当前调度上下文
    分配的系统资源,如文件描述符和网络端口

    进程的产生

    现有的(父)进程复制自己的地址空间(fork)来创建一个新的(子)进程结构。
    每个新进程分配有一个唯一的进程ID(PID),满足跟踪和安全性之需。PID与父进程ID(PPID)是新进程环境的元素。

    任何进程可创建子进程。所有进程都是第一个系统进程的后代。RHEL7上,第一个系统进程是systemd。

    通过fork例程,子进程继承安全性身份、过去和当前的文件描述符、端口和资源特权、环境变量,以及程序代码。随后,子进程可能exec其自己的程序代码。通常,父进程在子进程运行期间处于睡眠状态,设置一个在子进程完成时发出信号的请求(wait)。在退出时,子进程可能已经关闭或丢弃了其资源和环境,剩余的部分被称作僵停。父进程在子进程退出时收到信号而被唤醒,清理剩余结构,然后继续执行其自己的程序代码。

    进程的分类

    • 前台进程:与终端相关的进程,通过终端启动的进程
      • 注意:也可把在前台启动的进程送往后台,以守护模式运行
    • 守护进程:daemon,与终端无关的进程(如内核),在系统引导过程中启动的进程
    Excuting 运行态
    Ready 就绪态,也可以称作睡眠态
    Uninterruptible sleep 不可中断的睡眠。不可随时唤醒,只有当IO资源加载成功后才能唤醒
    Interruptible sleep|可中断的睡眠。可随时唤醒
    

    Zombie |僵尸进程。正常运行结束了,但是不释放占据的内存
    Stopped |停止态,暂停于内存中,但不会被调度,除非手动启动之

    进程睡眠的原因:
    当一个执行中的进程,需要加载额外的IO资源的时候,由于IO设备的速度太慢,所以会转入睡眠状态等待,交出CPU给其他进程,以免浪费剩余执行时间

    在多任务处理操作系统中,每个CPU(或CPU核心)在一个时间点上处理一个进程。在进程运行时,它对CPU时间和资源分配的直接要求会有变化。进程分配有一个状态,它随着环境要求而改变。

    Linux进程状态

    标志 内核定义的状态名称和描述
    R TASK_RUNNING:进程正在CPU上执行,或者正在等待运行。处于运行中(或可运行)状态时,进程可能正在执行用户例程或内核例程(系统调用),或者已排队并就绪
    S TASK_INTERRUPTIBLE:进程处于睡眠状态且正在等待某一条件:硬件请求、系统资源访问或信号。当事件或信号满足该条件时,该进程将返回到运行中
    D TASK_UNINTERRUPTIBLE:此进程也在睡眠,但与S状态不同,不会响应传递的信号。仅在特定的条件下使用,其中进程中断可能会导致意外的设备状态
    K TASK_KILLABLE:进程处于睡眠状态,与不可中断的D状态相同,但有所修改,允许等待中的任务通过响应信号而被中断(彻底退出)。实用程序通常将可中断的进程显示为D状态
    T TASK_STOPPED:进程已被停止(暂停),通常是通过用户或其他进程发出的信号。进程可以通过另一信号返回到运行中状态,继续执行(恢复)
    T TASK_TRACED:正在被调试的进程也会临时停止,并且共享同一个T状态标志
    Z EXIT_ZOMBIE:子进程在退出时向父进程发出信号。除进程身份(PID)之外的所有资源都已释放
    X EXIT_DEAD:当父进程清理(获取)剩余的子进程结构时,进程现在已彻底释放。此状态从不会在进程列出实用程序中看到
    < 高优先级进程
    N 低优先级进程
    + 前台进程组中的进程
    多线程进程
    s 会话进程首进程

    进程优先级

    linux进程调度与多任务

    现代计算机系统中既包含每次只能执行一个指令的低端处理器,也包含高性能超级计算机,这些超级计算机每台配备数百个CPU,每个CPU上具有多个核心,它们可以并行执行数以百计的指令。但是所有这些系统往往具有一个共同点:它们需要运行的进程数量总是超出实际具有的核心数。

    通过时间分片技术,Linux(和其他操作系统)实际能够运行的进程数(和线程数)可以超出可用的实际处理单元数。操作系统进程调度程序将在单个核心上的进程之间进行快速切换,从而给用户一种有多个进程在同时运行的印象。

    执行此切换的Linux内核部分称为进程调度程序。

    进程优先级

    进程优先级范围:0-139,数字越小,优先级越高
    0-99:实时优先级,内核调整
    100-139:静态优先级,用户可控制
    进程优先级高的特点:
    获得更多的CPU运行时间
    更优先获得CPU运行的机会
    要修改进程的优先级可以通过调整进程的nice值来实现,nice值越小,优先级越高:
    nice值的范围是(-20,19),-20对应100,19对应139

    相对优先级

    由于不是每种进程都与其他进程同样重要,可告知调度程序为不同的进程使用不同的调度策略。常规系统上运行的大多数进程所使用的调度策略称为SCHED_OTHER(也称为SCHED_NORMAL),但还有一些其他策略可用于不同的目的。

    由于并非所有进程都以同样的方式创建,可为采用SCHED_NORMAL策略运行的进程指定相对优先级。此优先级称为进程的nice值。一个进程可以有40种不同级别的nice值。

    这些nice级别的范围是从-20到19。默认情况下,进程将继承其父进程的nice级别,通常为0

    nice级别越高,表示优先级越低(该进程容易将其CPU使用量让给其他进程)
    nice级别越低,表示优先级越高(该进程更加不倾向于让出CPU)
    如果不存在资源争用(例如当活动进程数少于可用CPU核心数时),即使nice级别高的进程也将仍使用它们可使用的所有可用CPU资源。但当请求CPU时间的进程数超过可用核心数时,nice级别较高的进程将比nice级别较低的进程收到更少的CPU时间

    nice级别与权限

    为很占CPU资源的进程设置较低的nice级别可能会对同一系统上运行的其他进程的性能造成负面影响,所以仅允许root用户设置负nice级别以及降低现有进程的nice级别。

    普通非特权用户仅允许设置正的nice级别。只能对现有进程提升nice级别,而不能降低nice级别。

    进程优先级调整

    进程优先级调整:调整nice值

    • 调整已经启动的进程的nice值:
      renice NI PID(例:renice 3 3704)
    [root@hostnamectl ~]# ps elf
    F   UID    PID   PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
    4     0   1446   1406  20   0 115724  2344 do_wai Ss   pts/0      0:00 -bash USER=root LOG
    4     0   2340   1446  20   0 126236  1876 do_sig T    pts/0      0:00  \_ vi a XDG_SESSIO  //nice值0 ,pri 20,pid 2340
    0     0   2341   1446  20   0 148936  1448 -      R+   pts/0      0:00  \_ ps elf XDG_SESS
    4     0    826      1  20   0 110044   820 n_tty_ Ss+  tty1       0:00 /sbin/agetty --nocl
    
    [root@hostnamectl ~]# renice 10 2340
    2340 (进程 ID) 旧优先级为 0,新优先级为 10
    [root@hostnamectl ~]# ps elf
    F   UID    PID   PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
    4     0   1446   1406  20   0 115724  2344 do_wai Ss   pts/0      0:00 -bash USER=root LOG
    4     0   2340   1446  30  10 126236  1876 do_sig TN   pts/0      0:00  \_ vi a XDG_SESSIO //nice值10 ,pri 30,pid 2340
    0     0   2356   1446  20   0 148936  1448 -      R+   pts/0      0:00  \_ ps elf XDG_SESS
    4     0    826      1  20   0 110044   820 n_tty_ Ss+  tty1       0:00 /sbin/agetty --noc
    
    • 在启动时指定nice值:(-20,19)
      nice -n NI COMMAND
    [root@hostnamectl ~]# nice -n -20 vi b
    
    [root@hostnamectl ~]# ps elf
    F   UID    PID   PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
    4     0   2363   2359  20   0 115524  2112 do_wai Ss   pts/1      0:00 -bash USER=root LOG
    0     0   2380   2363  20   0 148936  1452 -      R+   pts/1      0:00  \_ ps elf XDG_SESS
    4     0   1446   1406  20   0 115724  2344 do_wai Ss   pts/0      0:00 -bash USER=root LOG
    4     0   2340   1446  30  10 126236  1876 do_sig TN   pts/0      0:00  \_ vi a XDG_SESSIO
    4     0   2358   1446   0 -20 126232  1792 poll_s S<+  pts/0      0:00  \_ vi b XDG_SESSIO
    4     0    826      1  20   0 110044   820 n_tty_ Ss+  tty1       0:00 /sbin/agetty --nocl
    

    进程管理命令

    Linux系统各进程的相关信息均保存在/proc/PID目录下的各文件中

    ps

    • ps(process state)命令用于列出当前的进程。可以显示详细的进程信息,包括:
      • 用户识别符(UID),它确定进程的特权
      • 唯一进程识别符(PID)
      • CPU和已经花费的实时时间
      • 进程在各种位置上分配的内存数量
      • 进程的位置STDOUT,称为控制终端
      • 当前的进程状态
    [root@hostnamectl ~]# ps
       PID TTY          TIME CMD
      1446 pts/0    00:00:00 bash
      2340 pts/0    00:00:00 vi
      2549 pts/0    00:00:00 vi
      2552 pts/0    00:00:00 vi
      2576 pts/0    00:00:00 ps
    
    • ps支持三种选项格式:

      • UNIX(POSIX)选项,可以分组但必须以连字符开头
      • BSD 选项,可以分组但不可与连字符同用
      • GNU 长选项,以双连字符开头
    • ps(process state),显示进程信息。注意事项:

      • 加了[]中括号的,表示内核线程,通常位于顶部
      • exiting或defunct表示僵尸进程
    • aux结果解析:

      VSZ Virtual memory SiZe,虚拟内存集
      RSS ReSident Size,常驻内存集
      STAT 进程状态
      TIME 运行时的累积时长
    • ps命令结果解析:

      NI nice值
      PRI 优先级
      PSR 进程运行在哪个CPU核心上
      RTPTRIO 实时优先级
      C 运行的CPU编号
      STIME 进程的启动时间
      VSZ Virtual memory SiZe,虚拟内存集
      RSS ReSident Size,常驻内存集
      STAT 进程状态
      TIME 运行时的累积时长
    • 常用选项:

    • a :显示所有与终端有关的进程

    [root@hostnamectl ~]# ps a
       PID TTY      STAT   TIME COMMAND
       826 tty1     Ss+    0:00 /sbin/agetty --noclear tty1 linux
      1446 pts/0    Ss     0:00 -bash
      2340 pts/0    TN     0:00 vi a
      2363 pts/1    Ss+    0:00 -bash
      2405 pts/0    R+     0:00 ps a
    
    • u :显示进程是由哪个用户启动的
    [root@hostnamectl ~]# ps au
    USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    root        826  0.0  0.0 110044   820 tty1     Ss+  13:57   0:00 /sbin/agetty --noclear tty1 linux
    root       1446  0.0  0.1 115724  2348 pts/0    Ss   13:57   0:00 -bash
    root       2340  0.0  0.1 126236  1876 pts/0    TN   18:00   0:00 vi a
    root       2363  0.0  0.1 115524  2112 pts/1    Ss+  18:06   0:00 -bash
    root       2406  0.0  0.0 151064  1816 pts/0    R+   18:17   0:00 ps au
    [root@hostnamectl ~]# 
    
    • x :显示所有与终端无关的进程
    [root@hostnamectl ~]# ps x
       PID TTY      STAT   TIME COMMAND
         1 ?        Ss     0:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 21
         2 ?        S      0:00 [kthreadd]
         3 ?        S      0:00 [ksoftirqd/0]
         5 ?        S<     0:00 [kworker/0:0H]
         7 ?        S      0:00 [migration/0]
         8 ?        S      0:00 [rcu_bh]
         9 ?        S      0:00 [rcu_sched]
        10 ?        S      0:00 [watchdog/0]
        11 ?        S      0:00 [watchdog/1]
        12 ?        S      0:00 [migration/1]
        13 ?        S      0:00 [ksoftirqd/1]
        15 ?        S<     0:00 [kworker/1:0H]
        16 ?        S      0:00 [watchdog/2]
        17 ?        S      0:00 [migration/2]
        18 ?        S      0:00 [ksoftirqd/2]
        20 ?        S<     0:00 [kworker/2:0H]
        21 ?        S      0:00 [watchdog/3]
        22 ?        S      0:00 [migration/3]
        23 ?        S      0:00 [ksoftirqd/3]
        25 ?        S<     0:00 [kworker/3:0H]
        27 ?        S      0:00 [kdevtmpfs]
        28 ?        S<     0:00 [netns]
    
    • -e :显示所有进程,与-A效果相同
    [root@hostnamectl ~]# ps -e
       PID TTY          TIME CMD
         1 ?        00:00:01 systemd
         2 ?        00:00:00 kthreadd
         3 ?        00:00:00 ksoftirqd/0
         5 ?        00:00:00 kworker/0:0H
         7 ?        00:00:00 migration/0
         8 ?        00:00:00 rcu_bh
         9 ?        00:00:00 rcu_sched
        10 ?        00:00:00 watchdog/0
        11 ?        00:00:00 watchdog/1
        12 ?        00:00:00 migration/1
        13 ?        00:00:00 ksoftirqd/1
        15 ?        00:00:00 kworker/1:0H
        16 ?        00:00:00 watchdog/2
        17 ?        00:00:00 migration/2
        18 ?        00:00:00 ksoftirqd/2
        20 ?        00:00:00 kworker/2:0H
        21 ?        00:00:00 watchdog/3
        22 ?        00:00:00 migration/3
        23 ?        00:00:00 ksoftirqd/3
        25 ?        00:00:00 kworker/3:0H
        27 ?        00:00:00 kdevtmpfs
        28 ?        00:00:00 netns
        29 ?        00:00:00 khungtaskd
        30 ?        00:00:00 writeback
        31 ?        00:00:00 kintegrityd
        32 ?        00:00:00 bioset
        33 ?        00:00:00 kblockd
        34 ?        00:00:00 md
        35 ?        00:00:09 kworker/0:1
        41 ?        00:00:00 kswapd0
        42 ?        00:00:00 ksmd
        43 ?        00:00:00 khugepaged
        44 ?        00:00:00 crypto
    
    • -l :以长格式显示
    [root@hostnamectl ~]# ps -l
    F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
    4 S     0   1446   1406  0  80   0 - 28931 do_wai pts/0    00:00:00 bash
    4 T     0   2340   1446  0  90  10 - 31559 do_sig pts/0    00:00:00 vi
    0 R     0   2414   1446  0  80   0 - 37235 -      pts/0    00:00:00 ps
    
    • -F :显示更详细的完整格式的进程信息
    [root@hostnamectl ~]# ps -F
    UID         PID   PPID  C    SZ   RSS PSR STIME TTY          TIME CMD
    root       1446   1406  0 28931  2348   2 13:57 pts/0    00:00:00 -bash
    root       2340   1446  0 31559  1876   3 18:00 pts/0    00:00:00 vi a
    root       2415   1446  0 37766  1784   3 18:21 pts/0    00:00:00 ps -F
    
    • j :工作的格式 (jobs format)
    [root@hostnamectl ~]# ps j
      PPID    PID   PGID    SID TTY       TPGID STAT   UID   TIME COMMAND
         1    831    831    831 tty1        831 Ss+      0   0:00 /sbin/agetty --noclear tty1 linux
      1437   1441   1441   1441 pts/0      1441 Ss+      0   0:00 -bash
      1457   1462   1462   1462 pts/1      1558 Ss       0   0:00 -bash
      1462   1486   1486   1462 pts/1      1558 T        0   0:00 -bash
      1462   1498   1498   1462 pts/1      1558 T        0   0:00 -bash
      1486   1546   1486   1462 pts/1      1558 T        0   0:00 sleep 1
      1498   1552   1498   1462 pts/1      1558 T        0   0:00 sleep 1
      1462   1558   1558   1462 pts/1      1558 R+       0   0:00 ps j
    [root@hostnamectl ~]# 
    
    • -H :以进程层级格式显示进程相关信息(PPDID是次子进程的父进程PID)
    [root@hostnamectl ~]# ps -efH
    UID         PID   PPID  C STIME TTY          TIME CMD
    root          2      0  0 14:14 ?        00:00:00 [kthreadd]
    root          3      2  0 14:14 ?        00:00:00   [ksoftirqd/0]
    root          4      2  0 14:14 ?        00:00:00   [kworker/0:0]
    root          5      2  0 14:14 ?        00:00:00   [kworker/0:0H]
    root          6      2  0 14:14 ?        00:00:00   [kworker/u256:0]
    root          7      2  0 14:14 ?        00:00:00   [migration/0]
    root          8      2  0 14:14 ?        00:00:00   [rcu_bh]
    root          9      2  0 14:14 ?        00:00:00   [rcu_sched]
    root         10      2  0 14:14 ?        00:00:00   [watchdog/0]
    root         11      2  0 14:14 ?        00:00:00   [watchdog/1]
    root         12      2  0 14:14 ?        00:00:00   [migration/1]
    root         13      2  0 14:14 ?        00:00:00   [ksoftirqd/1]
    root         14      2  0 14:14 ?        00:00:00   [kworker/1:0]
    root         15      2  0 14:14 ?        00:00:00   [kworker/1:0H]
    
    • -o :根据自己的需要选择要显示的字段
    [root@hostnamectl ~]# ps -o pid,comm,ni     表示只显示进程号,命令,nice值三个字段
       PID COMMAND          NI
      1446 bash              0
      2340 vi               10
      2404 ps                0
    

    pstree

    • pstree用于显示当前系统上的进程树
    [root@hostnamectl ~]# pstree
    systemd─┬─NetworkManager─┬─dhclient
            │                └─2*[{NetworkManager}]
            ├─VGAuthService
            ├─agetty
            ├─auditd───{auditd}
            ├─chronyd
            ├─crond
            ├─dbus-daemon───{dbus-daemon}
            ├─firewalld───{firewalld}
            ├─irqbalance
            ├─lvmetad
            ├─master─┬─pickup
            │        └─qmgr
            ├─polkitd───5*[{polkitd}]
            ├─rhnsd
            ├─rhsmcertd
            ├─rsyslogd───2*[{rsyslogd}]
            ├─sshd─┬─sshd───bash─┬─pstree
            │      │             └─vi
            │      └─sshd───bash
            ├─systemd-journal
            ├─systemd-logind
            ├─systemd-udevd
            ├─tuned───4*[{tuned}]
            └─vmtoolsd───{vmtoolsd}
    

    pgrep

    以grep风格指定只显示哪些进程,在当前系统中找符合某些特性的进程。只显示进程号

    [root@hostnamectl ~]# pgrep vi
    796
    2340
    
    [root@hostnamectl ~]# ps -ef|grep vi
    root        796      1  0 13:57 ?        00:00:00 /usr/bin/VGAuthService -s
    root       2340   1446  0 18:00 pts/0    00:00:00 vi a
    root       2472   1446  0 18:41 pts/0    00:00:00 grep --color=auto vi
    
    

    pidof

    根据进程名查找其PID号

    [root@hostnamectl ~]# pidof vi
    2340
    

    vmstat

    虚拟内存状态查看命令
    vmstat [options] [delay [count]]
    例:
    vmstat 2 :表示每2秒刷新一次
    vmstat 2 5 :表示每2秒刷新一次,刷新5次后退出

    [root@hostnamectl ~]# vmstat 2 2
    procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
     r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
     1  0      0 1508876   2108 196824    0    0     2     0   16   14  0  0 100  0  0
     0  0      0 1508876   2108 196824    0    0     0     0   55   44  0  0 100  0  0
    

    常用的选项:
    -s 显示内存的统计数据

    [root@hostnamectl ~]# vmstat -s
          1867048 K total memory
           159480 K used memory
           134368 K active memory
            81932 K inactive memory
          1508636 K free memory
             2108 K buffer memory
           196824 K swap cache
          2097148 K total swap
                0 K used swap
          2097148 K free swap
              318 non-nice user cpu ticks
                0 nice user cpu ticks
             1828 system cpu ticks
          7330335 idle cpu ticks
              269 IO-wait cpu ticks
                0 IRQ cpu ticks
               34 softirq cpu ticks
                0 stolen cpu ticks
           148185 pages paged in
            16745 pages paged out
                0 pages swapped in
                0 pages swapped out
          1146421 interrupts
          1025090 CPU context switches
       1569218250 boot time
             2649 forks
    

    procs:

    r(running) 表示等待运行的队列长度,也即等待运行的进程的个数
    b(block) 表示阻塞队列长度,也即处于不可中断睡眠态的进程个数

    memory:

    swpd /交换内存的使用总量
    free 空闲物理内存总量
    buffer 用于buffer的内存总量
    cache 用于cache的内存总量
    swap:
    si(swap in) 表示从物理内存有多少页面换进swap,也即数据进入swap的数据速率(kb/s)
    so(swap out) 表示从swap有多少页面换进物理内存,也即数据离开swap的数据速率(kb/s)
    io:
    bi(block in) 表示磁盘块有多少个被调入内存中,也即从块设备读入数据到系统的速率(kb/s)
    bo(block out) 表示有多少个磁盘块从内存中被同步到硬盘上去了,也即保存数据至块设备的速率(kb/s)

    system:

    in( interrupts) 表示中断的个数,也即中断速率(kb/s)
    cs(context switch) 表示上下文切换的次数,也即进程切换速率(kb/s)

    CPU:

    us 表示用户空间
    sy 表示内核空间
    id 表示空闲百分比
    wa 表示等待IO完成所占据的时间百分比
    st 表示steal,被虚拟化技术偷走的时间(比如运行虚拟机)
  • 相关阅读:
    WPF、UWP以及其他类型项目的csproj文件的迁移(SDK-Style)
    文书生成笔录预设保存按钮Mq中间转传服务
    卷宗添加争议焦点数据制造脚本(卷宗部分)
    案件信息同步之后,文书系统案件名称显示不正确问题
    DISTINCT----mysql移除返回的重复值
    Nginx系列教程(6)Nginx location 匹配规则详细解说
    转载 chrony 详解
    dmesg 时间转换
    axios---get和post用法详解
    通过递归来封装sessionStorage---set/get/delete
  • 原文地址:https://www.cnblogs.com/guilai/p/11581707.html
Copyright © 2020-2023  润新知