五、Linux进程管理

进程管理

一、进程概述以及属性介绍

1.1 进程概述

  • 进程是一个在系统中运行的程序,每个进程都是一个运行的实体,并占用一定的系统资源
  • 进程是已启动的可执行程序的运行实例,动态,有生命周期及运行状态
    • 程序:静态二进制文件,是可以实现特定目标或解决特定问题的代码集。例如:/bin/date/usr/sbin/httpd/usr/sbin/sshd/usr/local/nginx/sbin/nginx

1.2 进程的生命周期与PID/PPID

五、Linux进程管理_第1张图片

  • 父进程复制自己的地址空间(fork)创建一个新的(子)进程结构。每个新进程分配一个唯一的PID,满足跟踪安全性之需。PID和父进程ID(PPID)是子进程环境的元素,任何进程都可以创建子进程,所有进程都是第一个系统进程(init或systemd)的后代
  • 子进程继承父进程的安全性身份、过去和当前的文件描述符、端口和资源特权、环境变量,以及程序代码。随后,子进程可能exec(执行)自己的程序代码。通常,父进程在子进程运行期间处于睡眠(sleeping)状态。当子进程完成时发出(exit)信息请求,在退出时,子进程已经关闭或丢弃了其资源环境,剩余的部分称之为僵尸(zombie)。父进程在子进程退出时收到信号而被唤醒,清理剩余的结构,然后继续执行其自己的程序代码。

1.3 进程的状态

1.3.1 进程的状态(R,S,D,T,Z,X,t)

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

状态字母 说明
R 运行状态(runing),表明进程在运行中,或者在运行队列里,准备运行(并不意味着进程一定在运行中)
S 可中断睡眠状态(sleeping),意味着进程在等待事件的完成
D 磁盘睡眠状态(Disk sleep),也叫不可中断睡眠,在这个状态的进程通常会等待IO的结束
T 暂停状态(stopped),也叫跟踪状态,可以通过发送SIGSTOP信号,进程响应SIGSTOP信号而进入T暂停状态,这个被暂停的进程可以通过发送SIGCNT信号让进程继续运行
Z 僵尸状态(zombie),内核发送SIGCHKD信号通知父进程回收所有的资源
X 死亡状态(dead),这个状态只是一个返回状态,你不会在任务列表里看到这个状态
t 跟踪状态(tracing stop)

1.3.2 两种特殊的进程

  • 僵尸进程:当一个进程fork一个子进程之后,如果子进程退出,而父进程没有利用wait 或者waitpid 来获取子进程的状态信息时就会产生僵尸进程,那么子进程的状态描述符依然保存在系统中,并且会一直等待父进程读取退出状态代码

  • 孤儿进程:当一个父进程fork一个子进程之后,父进程突然被终止了,那么这个子进程就成为了一个孤儿进程,它会被init进程接管

  • 僵尸进程与孤儿进程的区别:

    • 孤儿进程是子进程还在运行,而父进程挂了,子进程被“init”进程(centos7中即systemd)收养。僵尸进程是父进程还在运行但是子进程挂了,但是父进程却没有使用wait来清理子进程的进程信息,导致子进程的状态描述符依然保存在系统中,子进程会一直等待父进程读取退出状态代码。这样长期下去对于系统资源是一个浪费,所以僵尸进程会浪费系统资源

1.4 进程类型

  • 守护进程daemon:在系统引导过程中启动的进程,跟终端无关的进程

  • 前台进程:跟终端相关,通过终端启动的进程

1.5 进程优先级

1.5.1 优先级引入

  • 每个CPU(或CPU核心)在一个时间点上只能处理一个进程,通过时间片技术,Linux实际能够运行的进程(和线程数)可以超出实际可用的CPU及核心数量。Linux内核进程调度程序将多个进程在CPU核心上快速切换,从而给用户多个进程在同时运行的假象。
  • 由于不是每个进程都与其他进程同样重要,可告知进程调度程序为不同的进程使用不同的调度策略。常规系统上运行的大多数进程所使用的的调度策略为SCHED_OTHER(也称为SCHED_NORMAL),SCHED_OTHER调度策略运行的进程的相对优先级称为进程的nice值

1.5.2 nice值

  • Nice值:-20~+19
  • NI 优先级,数值越小优先级越高,可以人为更改。(NI = NICE = Nice)
  • PR 优先级,将nice级别显示为映射到更大优先级队列,-20映射到0,+19映射到39

1.5.3 PR值

  • PRnice 值,都会影响进程执行的优先级。PROS内核动态调整,用户不能调整(PR值越低,进程执行的优先级越高)
  • 两者之间的关系:
    • nice值用户可以自己调整,在用户调整了nice值后系统会通过PR(新) = PR(旧) + nice 公式来调整新的PR值,从而确定这个进程在系统中的优先级
    • PR值是OS动态调整的,但是PR的最终值还是需要由OS分析决定的
      五、Linux进程管理_第2张图片

1.6 进程的权限

  • 系统上的每个进程(运行的程序)都是作为特定用户运行

  • 与正在运行的进程相关联的用户确定该进程可访问的文件和目录

  • 进程的六种权限(运维看看就行了,不重要,还是理解为进程用户与文件的权限关系)

    https://blog.csdn.net/ybxuwei/article/details/23563423

    • real user id、 real group id:简称ruid、rgid,由启动进程的用户决定,通常是当前登录用户(运行可执行文件的用户);
    • effective user id、effective group id:简称euid、egid ,一般在进程启动时,直接由ruid、rgid复制而来;或者是当进程对应的可执行文件的set-user-id/set-group-id(chmod u+s)标志位为true时,为该文件的所属用户/组,这组属性决定了进程访问文件的权限;
    • saved set-user-id、saved set-group-id简称suid/sgid,从euid/egid复制。可以理解为对euid/egid的一份备份。

1.7 进程的组成和内存占用

1.7.1 进程组成

  • 在Linux系统中进程由以下三部分组成:
    • 进程控制块PCB
    • 数据段
    • 正文段

1.7.2 进程控制块PCB

  • Linux系统为了节省进程控制块所占的内存空间,把每个进程控制块分成两部分。一部分常驻内存RSS,不管进程是否正占有处理器运行,系统经常会对这部分内容进行查询和处理

    • 常驻部分内容包括:进程状态、优先数、过程特征、数据段始址、等待原因和队列指针等,这是进行处理器调度时必须使用的一些主要信息
    • 另一部分非常驻内存,当进程不占有处理器时,系统不会对这部分内容进行查询和处理,因此这部分内容可以存放在磁盘的对换区中,它随用户的程序和数据部分换进或换出内存
  • PCB通常包含内容:
    五、Linux进程管理_第3张图片

  • 文件描述符fd:文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符

1.7.3 数据段

  • Linux系统把进程的数据段又划分成三部分
    • 用户栈区(供用户程序使用的信息区)
    • 用户数据区(包括用户工作数据和非可重入的程序段)
    • 系统数据区(包括系统变量和对换信息)

1.7.4 正文段

  • 正文段是可重入的程序,能被若干进程共享。为了管理可共享的正文段,Linux设置了一张正文表,每个正文段都占用一个表目,用来指出该正文段在内存和磁盘上的位置、段的大小以及调用该段的进程数等情况。

二、其他相关知识

2.1 systemd简介

2.1.1 初始化进程的概念

  • 首先systmed是一个用户空间的程序,属于应用程序,不属于Linux内核范畴。SystemdLinux系统中最新的初始化系(init),它主要的设计目标是克服sysvinit(这个是centos6中的初始化系统)固有的缺点,提高系统的启动速度。
  • Linux内核加载启动后,用户空间的第一个进程就是初始化进程,这个程序的物理文件约定位
    /sbin/init ,当然也可以通过传递内核参数来让内核启动指定的程序。
  • 这个进程的特点是进程号为1,代表第一个运行的用户空间进程。
  • 不同发行版采用了不同的启动程序,主要有以下几种主流选择:
    • Ubuntu为代表的Linux发行版采用upstart
    • centos7.0 版本之前的 System V init
    • centos7.0 版本的 systemd。centos7上所有的进程都是systemd的后代,systemd的功能繁多,不仅用来管理服务,还可以管理挂载点,定义定时任务等。这些工作都是由编辑相应的配置单元文件完成的。

2.1.2 systemd unit 类型

  • systemd需要管理的功能比较多,所以支持的配置单元类型也比较繁多,我们在日常使用Linux的过程中对系统服务的管理最多,所以我们主要了解一下service类型即可,其他类型作为一个了解,下面列举出所有类型详细的解释。
单元类型 文件格式 描述
Service unit .service 服务类
Target unit .target 一个unit服务组,用于模拟实现运行级别
Target unit .target 一个unit服务组,用于模拟实现运行级别
Automount unit .automount 文件系统自动挂载点
Device unit .device 内核识别的设备文件
Mount unit .mount 文件系统挂载点
Path unit .path 文件或目录
Scope unit .scope 外部创建的进程
Slice unit .slice 管理系统进程的一组分层组织的单元
Snapshot unit .snapshot 系统快照
Socket unit .socket 套接字
Swap unit .swap 标识swap设备
Timer unit .timer systemd的计时器

2.1.3 unit 文件保存位置

目录 描述
/usr/lib/systemd/system/ RPM包安装时分发的unit文件
/run/systemd/system/ systemd运行时创建的文件
/etc/systemd/system/ systemctl enable创建的unit文件

2.1.4 systemctl命令

  • 语法:systemctl [选项...] {命令} name.service
  • 功能:管理系统服务
  • 常用命令:
命令 描述
systemctl start name.service 启动服务
systemctl stop name.service 停止服务
systemctl restart name.service 重启服务(没启动的服务会启动)
systemctl try-restart name.service 只重启正在运行的服务
systemctl reload name.service 重载配置文件
systemctl status name.service systemctl is-activename.service 检查服务状态检查服务是否启动
systemctl list-units --type service --all 显示所有的服务状态
systemctl enable name.service 启用开机自启服务
systemctl disable name.service 停用自启服务
systemctl status name.service systemctl is-enabled name.service 检查服务状态查看服务是否自启
systemctl list-unit-files --type service 查看所有服务
systemctl list-dependencies --after 列出在指定服务之前启动的服务(依赖)
systemctl list-dependencies --before 列出在指定服务之后启动的服务(被依赖)

注:一个服务设置为开机启动使用会将/usr/lib/systemd/system/name.service 软链接到 /etc/systemd/system/ ,但是 enable 命令不会重写已经存在的链接,所以当我们修改了服务文件就需要重新加载systemctl reenable name.service

2.2 Linux下的内存(VM、Swap、RM、SM、buffer、cache)

  • 虚拟内存VM(virtual memory):是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。

    • Linux下面VM(虚拟内存)的大小由RM(Real Memory)swap组成,RM的大小就是物理内存的大小,而Swap的大小是由人为设定的。
    • 也有人只把swap当作虚拟内存,但其实swap是其中的一种
  • 实存储器RM(real memory):实际的物理内存空间,主存储器(内存)

  • 交互分区Swap:本质上属于硬盘虚拟出来的内存空间,读写速度相对RM(Real Memory)要慢许多。主要的功能是当实体内存不够时,在内存当中所占的程序会暂时被移动到 swap中,让实体内存(RM)可以被需要的程序来使用。另外,如果你的主机支持电源管理模式, 也就是说,你的 Linux主机系统可以进入“休眠”模式的话,那么, 运行当中的程序状态则会被纪录到swap去,以作为“唤醒”主机的状态依据! 另外,有某些程序在运行时,本来就会利用swap的特性来存放一些数据段。

    • 在Linux操作系统分区时,最少需要3个分区:
      • /boot分区 : 系统分区

      • swap交换分区 :一般情况下为内存的1~2倍,但是尽量不要超过2G,当计算机的内存不足时,系统会自动从硬盘中划出一块区域充当内存使用。

      • /分区 :根分区,所有文件都存放于此

  • 共享内存SM(Shared memory):多个进程之间共享的内存部分,比如公共库libc.so等。可以被不同中央处理器(CPU)访问的大容量内存

  • buffer缓冲区:是缓存将要放到硬盘里的数据

    • 用于存储速度不同步的设备或优先级不同的设备之间传输数据;
    • 通过buffer可以减少进程间通信需要等待的时间,当存储速度快的设备与存储速度慢的设备进行通信时,存储慢的数据先把数据存放到buffer,达到一定程度存储快的设备再读取buffer的数据,在此期间存储快的设备CPU可以干其他的事情。
  • cache缓存区:是缓存从硬盘读出来的数据

    • 是高速缓存,是位于CPU和主内存之间的容量较小但速度很快的存储器,因为CPU的速度远远高于主内存的速度,CPU从内存中读取数据需等待很长的时间,而Cache保存着CPU刚用过的数据或循环使用的部分数据,这时从Cache中读取数据会更快,减少了CPU等待的时间,提高了系统的性能。
    • Cache并不是缓存文件的,而是缓存块的(块是I/O读写最小的单元);Cache一般会用在I/O请求上,如果多个进程要访问某个文件,可以把此文件读入Cache中,这样下一个进程获取CPU控制权并访问此文件直接从Cache读取,提高系统性能。

2.3 Linux进程通信的几种方式

  1. 无名管道pipe:管道是一种半双工的通信万式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
    • 特点:所有的UNIX都支持、中间介质是文件、使用需要维护管道开发量大些;
  2. 命名管道FIFO:有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。(特点同上)
  3. 消息队列MessageQueue:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点
    • 特点:不是所有的UNIX都支持,以消息缓冲区为中间介质,需要操作权限,传递的数据有标准格式,开发人员解析方便;
  4. 共享存储SharedMemory:共享内存就是映射一段能被其他进程所访问的内存这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的IPC方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。
    • 特点:最快的通信方式
  5. 信号量Semaphore:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
  6. 套接字Socket:套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。
    • 特点:可本地可远程
  7. 信号sinal:信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生
    • 局限性:开销太大,发送信号进程需通过系统调用,先中断接受信号进程、调用信号处理程序、恢复该进程,传递的信息量及数量受限制,不宜复杂数据通信。

2.4 用户模式和内核模式

  • 为了保证用户进程不能直接操作内核,保证内核安全,操作系统将虚拟空间划分为两部分(用户空间和内核空间)
    • 内核模式Kernel Mode:执行代码可以完全且不受限制地访问底层硬件。它可以执行任何CPU指令和引用任何内存地址。内核模式通常为操作系统的最低级别、最受信任的功能保留。内核模式下的崩溃是灾难性的,他们会让整个电脑瘫痪。
    • 用户空间User Mode:在用户模式下,执行代码不能直接访问硬件或引用内存。在用户模式下运行的代码必须委托给系统调用来访问硬件或内存。由于这种隔离提供的保护,用户模式下的崩溃总是可恢复的。在计算机上运行的大多数代码将在用户模式下执行。
  • 何时进行模式切换?
    • 应用程序一般会在以下几种情况下切换到内核模式:
      • 系统调用
      • 异常事件。当发生某些预先不可知的异常时,就会切换到内核态,以执行相关的异常事件。
      • 设备中断。在使用外围设备时,如外围设备完成了用户请求,就会向CPU发送一个中断信号,此时,CPU就会暂停执行原本的下一条指令,转去处理中断事件。此时,如果原来在用户态,则自然就会切换到内核态。
  • CPU的特权级别
    • Ring 0 表示内核态,Ring 3表示用户态,越内部的圈代表的权限越大
    • 操作系统(内核)的代码运行在最高运行级别Ring 0上,可以使用特权指令,控制中断、修改页表、访问设备等等。
    • 应用程序的代码运行在最低运行级别上Ring3上,不能做受控操作。如果要做,比如要访问磁盘,写文件,那就要通过执行系统调用(API),执行系统调用的时候,CPU的运行级别会发生从Ring 3Ring 0的切换,并跳转到系统调用对应的内核代码位置执行,这样内核就为你完成了设备访问,完成之后再从Ring 0返回Ring 3。这个过程也称作用户态和内核态的切换
      五、Linux进程管理_第4张图片

2.5 软/硬中断

  • 中断是一种异步的事件处理机制,可以提高系统的并发处理能力

  • 硬中断:简答理解为CPU外部的硬件,引入的中断,随机的

    • 由与系统相连的外设(比如网卡、硬盘)自动产生的。主要是用来通知操作系统系统外设状态的变化。比如当网卡收到数据包的时候,就会发出一个中断。我们通常所说的中断指的是硬中断
  • 软中断:CPU中运行的软件(进程)中断指令,引入的中断,预先设计的。

    • 为了满足实时系统的要求,中断处理应该是越快越好。linux为了实现这个特点,当中断发生的时候,硬中断处理那些短时间就可以完成的工作,而将那些处理事件比较长的工作,放到中断之后来完成,也就是软中断来完成。
    • 软中断的处理非常像硬中断。然而,它们仅仅是由当前正在运行的进程所产生的
    • 软中断并不会直接中断CPU。也只有当前正在运行的代码(或进程)才会产生软中断。这种中断是一种需要内核(通常以内核线程的方式)为正在运行的进程去做一些事情(通常为IO)的请求。每个CPU都对应一个软中断内核线程,名字为ksoftirqd/CPU编号,比如说, 0 号 CPU 对应的软中断内核线程的名字就是ksoftirqd/0
    • 当软中断事件频率过高的时候,内核也会因为cpu使用率过高而导致软中断处理不及时,进而引发网络收发延迟、调度缓慢等性能问题
  • 差别

    • 硬中断是由外部事件引起的因此具有随机性和突发性
      软中断是执行中断指令产生的,无面外部施加中断请求信号,因此中断的发生不是随机的而是由程序安排好的

    • 硬中断的中断响应周期,CPU需要发中断回合信号(NMI不需要)
      软中断的中断响应周期,CPU不需发中断回合信号

    • 硬中断的中断号是由中断控制器提供的(NMI硬中断中断号系统指定为02H)

      软中断的中断号由指令直接给出,无需使用中断控制器

    • 硬中断是可屏蔽的(NMI硬中断不可屏蔽)
      软中断不可屏蔽

  • linux将中断过程分为了两个阶段:

  1. 上半部分:用来快速处理中断,它在中断禁止模式下运行,主要处理跟硬件相关的时间敏感的工作(直接处理硬件请求,也就是我们常说的硬中断,特点是快速执行)
  2. 下半部分:用来延迟处理上半部分未完成的工作,通常以内核线程的方式运行(由内核触发,也就是我们常说的软中断,特点是延迟执行)
  • 例子

网卡在接收数据包后,会通过硬中断的方式,通知内核有新的数据包到了,这时候内核就应该调用中断处理程序来响应它,对于上半部分既然是快速处理中断,就是把网卡中的数据读到内存中,然后更新硬件寄存器的状态(表示数据已经读取好了),最后再发送一个软中断信号,通知下半部分做进一步处理。
而下半部被软中断信号唤醒后,需要从内存中找到网络数据,再按照网络协议栈,对数据
进行逐层解析和处理,直到把它送给应用程序。

  • 查看软中断和内核线程

    • /proc/softirqs :提供软中断的运行情况

    • /proc/interrupts:提供硬中断的运行情况

2.6 线程与协程

  • 进程Process):是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位

    • 进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。
    • 进程是一个实体!每一个进程都有自己的地址空间(文本区域,数据区域,堆栈)。
  • 线程Thread):是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。多个线程相对独立,有自己的上下文,切换受系统控制

    • 多进程不会共享全局变量,因为进程是独立的,线程之间是可以共享的进程是一个资源分配的总和,线程是拿资源去执行
    • 多进程多任务是多个资源每个资源至少1个人做事
    • 多线程多任务一个资源多个人做事
  • 协程Coroutines)是一种比线程更加轻量级的存在,正如一个进程可以拥有多个线程一样,一个线程可以拥有多个协程。

    • 协程不是被操作系统内核所管理的,而是完全由程序所控制,也就是在用户态执行。这样带来的好处是性能大幅度的提升,因为不会像线程切换那样消耗资源
  • 三者比较

    • 协程既不是进程也不是线程,协程仅仅是一个特殊的函数,协程它和进程不是一个维度的。

    • 一个进程可以包含多个线程,一个线程可以包含多个协程。

    • 一个线程内的多个协程虽然可以切换,但是多个协程是串行执行的,只能在一个线程内运行,没法利用CPU多核能力。(同样,单核cpu的多线程也无法并行)

    • 协程与进程一样,切换是存在上下文切换问题的。

注:其余进程的基础知识(单核/多核调度策略、上下文等)去学操作系统吧,东西太多了,枯燥但是重要的概念,到此为止


三、进程管理

3.1 查看进程及其相关信息

3.3.1 top命令

  • 语法:top [选项]
  • 功能:动态监测进程
  • 常用参数
参数 说明
d 改变显示的更新速度,或是在交谈式指令列( interactive command)s
q 没有任何延迟的显示速度,如果使用者是有superuser的权限,则top将会以最高的优先序执行
c 切换显示模式,共有两种模式,一是只显示执行档的名称,另一种是显示完整的路径与名称
S 累积模式,会将己完成或消失的子行程 ( dead child process )CPU time 累积起来
s 安全模式,将交谈式指令取消, 避免潜在的危机
i 不显示任何闲置(idle)或无用(zombie)的进程
n 更新的次数,完成后将会退出top
b 批次档模式,搭配 “n” 参数一起使用,可以用来将 top 的结果输出到档案内
  • 示例
top 
top -n 2 # 更新两次后终止更新显示
top -d 1 # 一秒钟刷新一次 
top -d 1 -p 6995 # 查看指定PID 
top -d 1 -p 6995,1 # 查看多个PID进程 
top -d 1 -u apache # 查看指定用户的进程 
top -d 1 -b -n 2 > top.txt # 将2次top信息写入到文件
top -c # 显示完整命令
  • 允许结果字段
top - 16:27:42 up 5 min,  1 user,  load average: 0.01, 0.10, 0.06
Tasks: 117 total,   1 running, 116 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.1 us,  0.0 sy,  0.0 ni, 99.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  3861512 total,  3373748 free,   296648 used,   191116 buff/cache
KiB Swap:  2097148 total,  2097148 free,        0 used.  3327836 avail Mem 
PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND 
  • top前五行字段解析

  • 第一行:

top - 16:27:42 up 5 min,  1 user,  load average: 0.01, 0.10, 0.06
内 容 说 明
16:27:42 系统时间
up 5 min 运行时间
1 user 登录终端数
load average: 0.01, 0.10, 0.06 系统在之前 1 分钟、5 分钟、15 分钟的平均负载。
该值若超过系统CPU核数,则为超负荷运行
  • 注:这里的系统平均负载指:单位时间内,系统处于可运行状态R(正在使用cpu和等待使用cpu的进程)和不可中断状态D (内核态关键流程)的平均的进程数占比(即处于运行和不可中断的进程在CPU上的百分比)

  • 第二行

Tasks: 117 total,   1 running, 116 sleeping,   0 stopped,   0 zombie
内 容 说 明
Tasks: 117 total 进程总数
1 running 正在运行的进程数
116 sleeping 睡眠的进程数
0 stopped 停止的进程数
0 zombie 僵尸进程数。若非 0,需要手工检查僵尸进程
  • 第三行
%Cpu(s):  0.1 us,  0.0 sy,  0.0 ni, 99.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
内 容 说 明
%Cpu(s) CPU占比
0.1 us user用户模式CPU占比
0.0 sy system系统模式CPU占比
0.0ni nice改变过优先级(nice值)的用户进程CPU占比
99.9 id idle空闲CPU占比
0.0wa wait等待I/O的进程CPU占比
0.0hi 硬中断请求服务的CPU占比
0.0si 软中断请求服务的CPU占比
0.0st steal time虚拟时间的CPU占比,虚拟机 CPU 等待实际 CPU 的时间占比
  • 获取CPU核数
[root@server1 ~]# grep 'core id' /proc/cpuinfo | wc -l
4
  • CPU负载测试 => cat /dev/urandom |md5sum

  • 第四行

KiB Mem :  3861512 total,  3373748 free,   296648 used,   191116 buff/cache
内 容 说 明
KiB Mem 物理内存,单位为KB
3861512 total 总内存
3373748 free 空闲的内存
296648 used 己经使用的内存
191116 buff/cache 作为缓冲的内存
  • 第五行
KiB Swap:  2097148 total,  2097148 free,        0 used.  3327836 avail Mem 
PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND 
内 容 说 明
KiB Swap 交换分区,单位为KB
2097148 total 交换分区的总大小
2097148 free 空闲的交换分区
0 used 已经使用的交换分区的大小
3327836 avail Mem 已被提前加载的内存量
  • 第六行加粗字段
PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
字段 说明
PID 进程ID
USER 进程所属的用户
PR 优先级,数值越小优先级越高
NI Nice优先级,数值越小优先级越高,取值范围-20到19,默认都是0
VIRT 虚拟内存大小,单位KB
RES 物理内存大小,单位KB
SHR 共享内存大小,单位KB
S 进程状态
%CPU 该进程占用CPU的百分比
%MEM 该进程占用内存的百分比
TIME+ 该进程共占用的CPU时间
COMMAND 进程名
  • 常用快捷键
按键 作用
M 按内存的使用排序
P CPU使用排序
N PID的大小排序
R 对排序进行反转
1 显示所有CPU的负载
z 彩色
q 退出

3.3.2 ps命令

  • 语法:ps [选项]
  • 功能:静态查看进程信息。日常ps命令常用于查询某个进程的PIDPPID或者结合grep获取某个具体进程的信息
  • 常用选项
选项 参数
-e 列出全部进程
-f full,显示全字段
-ef 显示全部进程
-u 以用户为中心组织进程状态信息显示
-a 与终端相关的进程
-x 与终端无关的进程
-aux 显示全部进程
  • ps -aux不同于ps auxPOSIXUNIX标准要求ps -aux打印名为x的用户拥有的所有进程,如果名为x的用户不存在,此时ps会将该命令解释为ps aux
[root@server1 ~]# ps -ef
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  3 10:50 ?        00:00:01 /usr/lib/systemd/systemd --switched-root --system --deserial
...

[root@server1 ~]# ps -ef|grep mysql
root       8928      1  0 10:50 ?        00:00:00 /bin/sh /app/mysql/bin/mysqld_safe --datadir=/mysql/data --pid-file=/mysql/data/server1.pid
mysql      9269   8928  0 10:50 ?        00:00:01 /app/mysql/bin/mysqld --basedir=/app/mysql --datadir=/mysql/data --plugin-dir=/app/mysql/lib/plugin --user=mysql --log-error=server1.err --pid-file=/mysql/data/server1.pid --socket=/tmp/mysql.sock --port=3306
root      18979  10809  0 10:53 pts/0    00:00:00 grep --color=auto mysql
#以上信息最后一行是grep命令所启动的进程

# grep -v取反
[root@server1 ~]# ps -ef|grep mysql|grep -v "grep"
root       8928      1  0 10:50 ?        00:00:00 /bin/sh /app/mysql/bin/mysqld_safe --datadir=/mysql/data --pid-file=/mysql/data/server1.pid
mysql      9269   8928  0 10:50 ?        00:00:01 /app/mysql/bin/mysqld --basedir=/app/mysql --datadir=/mysql/data --plugin-dir=/app/mysql/lib/plugin --user=mysql --log-error=server1.err --pid-file=/mysql/data/server1.pid --socket=/tmp/mysql.sock --port=3306
root      18981  10809  0 10:54 pts/0    00:00:00 grep --color=auto mysql
[root@server1 ~]# ps -aux
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.3  0.0 125284  3772 ?        Ss   10:50   0:01 /usr/lib/systemd/systemd --switched-root --s
....

# 其他常用用法
# 按照CPU使用率排序查看所有进程
[root@server1 ~]# ps aux --sort %cpu # 递增
[root@server1 ~]# ps aux --sort -%cpu # 递减
# 按照实际内存使用排序查看所有进程
[root@server1 ~]# ps aux --sort rss # 递增
[root@server1 ~]# ps aux --sort -rss # 递减
# 自定义显示格式
[root@server1 ~]# ps -axo user,pid,ppid,%mem,%cpu,command --sort -%cpu
# 查看指定进程的PID,多种查看的方式
[root@server1 ~]# cat /run/sshd.pid
[root@server1 ~]# ps aux |grep sshd
[root@server1 ~]# pgrep -l sshd
[root@server1 ~]# pidof sshd
  • 字段解释
字段 说明
UID 用户ID
PID 进程ID
PPID 该进程的父级进程ID,如果找不到,则该进程就被称之为僵尸进程
C或%CPU CPU的占用率,其形式是百分数
STIME 进程的启动时间
TTY 终端设备,显示“?”则表示该进程并不是由终端设备发起
TIME 进程实际使用CPU的时间
CMD 该进程的名称或者对应的路径
USER 用户
%MEM 内存的占用率
VSZ 进程占用的虚拟内存
RSS 进程占用的常驻内存大小
STAT 进程目前的状态

3.3.3 netstat/ss命令

  • 语法:netstat/ss [选项]
  • 功能:查询进程端口号
  • 两条命令用法几乎一模一样,用哪个都行,ss
  • 常用选项
选项 说明
-t 表示只列出tcp协议的连接
-u 表示只列出udp协议的连接
-n 表示将地址从字母组合转化成ip地址,将协议转化成端口号来显示
-l 只列中LISTEN(监听)的连接
-p 显示进程pid和进程名称
[root@server1 ~]# netstat -tnlp
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      8891/sshd           
tcp6       0      0 :::3306                 :::*                    LISTEN      9269/mysqld         
tcp6       0      0 :::22                   :::*                    LISTEN      8891/sshd 
[root@server1 ~]# netstat -tnlp|grep mysqld
tcp6       0      0 :::3306                 :::*                    LISTEN      9269/mysqld 
[root@server1 ~]# ss -tnlp
State      Recv-Q Send-Q          Local Address:Port                         Peer Address:Port              
LISTEN     0      128                         *:22                                      *:*                   users:(("sshd",pid=8891,fd=3))
LISTEN     0      80                         :::3306                                   :::*                   users:(("mysqld",pid=9269,fd=35))
LISTEN     0      128                        :::22                                     :::*                   users:(("sshd",pid=8891,fd=4))
[root@server1 ~]# ss -tnlp|grep mysqld
LISTEN     0      80          :::3306                    :::*                   users:(("mysqld",pid=9269,fd=35))

3.3.4 free命令

  • 语法:free [选项]
  • 功能:查看内存信息,默认是KB为单位
  • 常用选项
    • -b/k/m/g:分别以B/KB/MB/GB为单位
    • -h:以可阅读人性化的方式查看
[root@server1 ~]# free -m
              total        used        free      shared  buff/cache   available
Mem:           3771         288        3248          11         234        3227
Swap:          2047           0        2047
[root@server1 ~]# free -h
              total        used        free      shared  buff/cache   available
Mem:           3.7G        288M        3.2G         11M        234M        3.2G
Swap:          2.0G          0B        2.0G

3.2 使用信号控制进程

列出所有支持的信号
[root@server1 ~]# 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
  • 常用信号
编号 信号名 作用
1 SIGHUP 重新加载配置
2 SIGINT 键盘中断^C
3 SIGQUIT 键盘退出
9 SIGKILL 强制终止
15 SIGTERM 终止(正常结束)
18 SIGCONT 继续
19 SIGSTOP 停止
20 SIGTSTP 暂停^Z

3.2.1 kill/killall

  • 语法:kill [选项/信号] PID killall [选项/信号] 进程名
  • 功能:向进程发出信号,常用于杀死或重载配置等
# 根据pid发射信号(建议用来结束单个进程)
[root@server1 ~]# ps -ef | grep crond | grep -v 'grep'
root        684      1  0 12:01 ?        00:00:00 /usr/sbin/crond -n
[root@server1 ~]# kill  684  #不加选项,默认为-15,终止进程
[root@server1 ~]# ps -ef | grep crond | grep -v 'grep'

[root@server1 ~]# ps -ef | grep crond | grep -v 'grep'
root      11767      1  0 17:13 ?        00:00:00 /usr/sbin/crond -n
# -9强制终止进程
[root@server1 ~]# kill -9 11767 
[root@server1 ~]# ps -ef | grep crond | grep -v 'grep'

# 根据进程名结束进程(可一次结束多个进程,包括父进程fork出的子进程)
[root@server1 ~]# systemctl restart crond.service 
[root@server1 ~]# killall crond
[root@server1 ~]# ps -ef | grep crond | grep -v 'grep'

3.2.2 pkill命令

  • 语法:pkill [选项] 终端/用户名/进程名
  • 功能:踢出远程登录用户,也可用于杀死进程(此时用法同killall)
  • 常用参数
    • -t:指定踢出终端
    • -u:指定踢出终端上登录的用户
[root@server1 ~]# w
 17:24:29 up  5:23,  3 users,  load average: 0.03, 0.02, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     tty1                      12:01    5:20m  0.10s  0.00s bash
root     pts/0    192.168.226.1    14:52    5.00s  0.08s  0.00s w
root     pts/1    192.168.226.1    17:22   13.00s  0.01s  0.00s -bash
[root@server1 ~]# pkill -t pts/1
[zhangsan@server1 ~]$ 
Session terminated, killing shell... ...已杀死。

[root@server1 ~]# w
 17:30:23 up  5:28,  4 users,  load average: 0.00, 0.01, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     tty1                      12:01    5:25m  0.10s  0.00s bash
root     pts/0    192.168.226.1    14:52    7.00s  0.08s  0.00s w
root     pts/1    192.168.226.1    17:22   31.00s  0.01s  0.01s -bash
zhangsan pts/2    192.168.226.1    17:30    5.00s  0.00s  0.00s -bash
[root@server1 ~]# pkill -u zhangsan
[zhangsan@server1 ~]$ Connection closing...Socket close.
Connection closed by foreign host.
Disconnected from remote host(192.168.226.10:22) at 23:02:56.
Type `help' to learn how to use Xshell prompt.
[D:\~]$ 

3.3 作业控制

  • 作业控制是一个命令行功能,允许一个shell实例来运行和管理多个命令。

    • 如果没有作业控制,父进程fork()一个子进程后,将sleeping,直到子进程退出(表现为界面一直在运行子进程命令,无法输入新命令)
    • 使用作业控制,可以选择性暂停,恢复,以及异步运行命令,让shell可以在子进程运行期间返回接受其他命令
  • 作用:

    • 将任务进行前台后台的切换
    • 可以控制进程运行或者停止
  • 前台:foreground ,前台进程是在终端中运行的命令,该终端为进程的 控制终端 。前台进程接受键盘产生的输入和信号,并允许从终端读取或写入到终端。

  • 后台:background ,后台进程没有控制终端 ,它不需要终端的交互。

3.3.1 jobs、fg、bg命令

  • jobs:查看后台作业
  • fg:将后台作业调回前台
    • 语法:fg %num
  • bg:让后台停止的作业在后台运行
    • 语法:bg %num
  • &:将程序放到后台执行
  • Ctrl + z:将前台的程序挂起(暂停)到后台
  • Ctrl + c:终止前台作业
  • sleep:用于延迟shell运行时间,默认单位为s
[root@server1 ~]# sleep 3000 &
[1] 11898
[root@server1 ~]# sleep 2000
^Z
[2]+  已停止               sleep 2000
[root@server1 ~]# ps -ef | grep sleep | grep -v 'grep'
root      11898  11488  0 17:45 pts/0    00:00:00 sleep 3000
root      11900  11488  0 17:49 pts/0    00:00:00 sleep 2000

# 查看后台作业
[root@server1 ~]# jobs
[1]-  运行中               sleep 3000 &
[2]+  已停止               sleep 2000

# 让后台停止的作业在后台运行
[root@server1 ~]# bg %2
[2]+ sleep 2000 &
[root@server1 ~]# jobs
[1]-  运行中               sleep 3000 &
[2]+  运行中               sleep 2000 &

# 将后台作业调回前台
[root@server1 ~]# fg %1
sleep 3000

# 终止前台作业^C

3.3.2 nohup命令

  • 虽然可以将程序放在后台运行,但是一旦关闭远程连接那么程序就会中断,如果我们想要将程序一直保持在后台运行,那么我们可以有如下三个选择:
    • 把需要在后台执行的命令加入 /etc/rc.local 文件,让系统在启动时执行这个后台程序。这种方法的问题是,服务器是不能随便重启的,如果有临时后台任务,就不能执行了
    • 使用系统定时任务,让系统在指定的时间执行某个后台命令。这样放入后台的命令与终端无关,是不依赖登录终端的
    • 使用 nohup 命令
  • 语法:nohup 命令 [&]
  • 功能:将程序放在后台运行和连接窗口无关,并将结果默认输出到~/nohup.out
  • &的区别:&放在后台的命令随着ssh连接窗口的关闭就会停止,nohup不会,一般一起用
  • 示例
[root@server1 ~]# nohup ping baidu.com &
[root@server1 ~]# ps aux |grep ping
root    7157 0.0 0.0 149968 1988 ?    S  14:12  0:00 ping baidu.com
[root@server1 ~]# tail -f nohup.out
# 同样可以用jobs查看,kill -9 pid杀死

3.4 调整进程的优先级

3.4.1 top交互

# 获取进程PID
[root@server1 ~]# top -bn 1  #静态一屏获取所有进程信息
 685 root      20   0   25908    956    756 S   0.0  0.1   0:00.00 atd

# 交互修改
[root@server1 ~]# top
r-->685-->-5-->q
PID to renice [default pid = 1] 685
Renice PID 685 to value -5

# 查看
[root@server1 ~]# top -p 685 #只查看pid=685的进程的信息
  685 root      15  -5   25908    956    756 S   0.0  0.1   0:00.00 atd 

3.4.2 renice

  • 语法:nice [nice值] PID
  • 功能:修改进程的nice
  • 示例
# 获取进程PID
[root@server1 ~]# ps -ef |grep atd |grep -v 'grep'
root        685      1  0 12:01 ?        00:00:00 /usr/sbin/atd -f

# 调整NICE值
[root@server1 ~]# renice -10 685
685 (进程 ID) 旧优先级为 -5,新优先级为 -1

3.4.3 nice

  • 语法:nice [选项] 命令
  • 功能:设置或修改程序的优先级并运行
  • 常用参数
    • -n :设置nice值
  • 注意:nice命令只能调整没有运行的程序
nice -n 1 ls # 将 ls 的优先级设置为 1 并执行
nice ls # 将 ls 的优先级加 10 并执行,默认是设置为10

# 关闭
[root@server1 ~]# ps -ef |grep crond |grep -v 'grep'
root       8536      1  0 12:36 ?        00:00:00 /usr/sbin/crond -n
[root@server1 ~]# kill 8536

# nice调整优先级,并启动程序
[root@server1 ~]# nice -n -10 crond

# 查看
[root@server1 ~]# ps -ef |grep crond
root       8542      1  0 12:38 ?        00:00:00 crond
[root@server1 ~]# top -p 854
 8542 root      10 -10  126384   1320    716 S   0.0  0.1   0:00.00 crond 

你可能感兴趣的:(01.Linux管理,linux,服务器,运维)