内核(kernel,操作系统的核心部分)是实现进程管理、内存管理、网络管理、驱动程序、文件系统、安全功能等功能
内核有两种设计流派
- 宏内核(monolithic kernel):又称单内核和强内核,Unix,Linux把所有系统服务都放到内核里,所有功能集成于同一个程序,分层实现不同功能,系统庞大复杂,Linux其实在单内核内核实现了模块化,也就相当于吸收了微内核的优点。
- 微内核(micro kernel):Windows,Solaris,HarmonyOS简化内核功能,在内核之外的用户态尽可能多地实现系统服务,同时加入相互之间的安全保护,每种功能使用一个单独子系统实现,将内核功能移到用户空间,性能差。
计算机一般是不会同时处理两个及以上任务的,计算机的处理方式是以不断的切换,正在运行的叫做进程,等待运行或休眠状态的叫做程序
一、进程
1.程序
程序的定义:
- 是一组计算机能识别和执行的指令,运行于电子计算机上,满足人们某种需求的信息化工具。
- 用于描述进程要完成的功能,是控制进程执行的指令集。
- 保存在硬盘、光盘等介质中的可执行代码和数据。
- 静态保存的代码。
2 进程(Process)
运行中的程序的一个副本,是被载入内存的一个指令集合,是资源分配的单位。
进程的定义:
- 在CPU及内存中运行的程序代码
- 动态执行的代码
- 进程ID(Process ID,PID)号码被用来标记各个进程
- UID、GID、和SELinux语境决定对文件系统的存取和访问权限
- 通常从执行进程的用户来继承
- 存在生命周期
- 都由其父进程创建
进程是已启动的可执行程序的运行实例,
进程的组成部分:
- 已分配内存的地址空间;
- 安全属性,包括所有权凭据和特权;
- 有权限限制;
- 程序代码的一个或多个执行线程;
进程的优先级:
一般进程的优先级都是默认的,可以通过设置进程NI(-20~19)来设置进程优先级,优先级=PRI+NI,数值越低,优先级越高
PRI 代表 Priority,NI 代表 Nice。 这两个值都表示优先级,数值越小代表该进程越优先被 CPU 处理。
PRI值是由内核动态调整的,用户不能直接修改。 我们只能通过修改 NI 值来影响 PRI 值,间接地调整进程优先级。
注意事项:
- NI 范围是 -20~19。
- 普通用户调整 NI 值的范围是 0~19,而且只能调整自己的进程。
- 普通用户只能调高 NI 值,而不能降低。如原本 NI 值为 0,则只能调整为大于 0。
- 只有 root 用户才能设定进程 NI 值为负值,而且可以调整任何用户的进程
示例:
PRI (最终值) = PRI (原始值) + NI
PRI越小,优先级越高
#查看命令及格式
ps axo pid,cmd,ni
[root@centos8 ~]#nice -n -10 ping 127.0.0.1
[root@centos7 ~]#renice -n -20 2118
进程的分类与类型:
操作系统分类:
协作式多任务:早期的windows系统使用,一个任务会霸占一整个cpu,效率十分低
抢占式多任务:linux内核,cpu会轮流处理任务,一定时间后会剥夺任务使用权,执行下一个任务,由此循环
进程类型:
守护进程:daemon,在系统引导过程中启动的进程,和终端无关
前台进程:和终端相关,通过终端启动的进程
父进程与子进程:
父进程复制自己的地址空间(fork派生)创建一个新的(子)进程结构。
每个进程分配一个唯一的进程ID(PID),满足跟踪安全性之需。
任何进程都可以创建子进程。
所有进程都是第一个系统进程的后代(init或systemd)
进程的特征
- 动态性:进程是程序的一次执行过程,是临时的,有生命期的,是动态产生,动态消亡的;
- 并发性:任何进程都可以同其他进程一起并发执行;
- 独立性:进程是系统进行资源分配和调度的一个独立单位;
- 结构性:进程由程序、数据和进程控制块三部分组成。
僵尸进程
僵尸进程是当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程将成为一个僵尸进程。如果父进程先退出 ,子进程被init接管,子进程退出后init会回收其占用的相关资源。
遇到僵尸进程有两种解决方案:
- 恢复父进程(
kill-18pid) - 杀死父进程(
kill-9pid)
PS:kill是一个信号命令,可以通过这个命令来给进程传递信号,可以通过kill -l来查找使用需要的指令
3.进程状态
进程的基本状态:
- 创建状态:进程在创建时需要申请一个空白PCB(process control block进程控制块),向其中填写控制和管理进程的信息,完成资源分配。如果创建工作无法完成,比如资源无法满足,就无法被调度运行,把此时进程所处状态称为创建状态
- 就绪状态:进程已准备好,已分配到所需资源,只要分配到CPU就能够立即运行
- 执行状态:进程处于就绪状态被调度后,进程进入执行状态
- 阻塞状态:正在执行的进程由于某些事件(I/O请求,申请缓存区失败)而暂时无法运行,进程受到阻塞。在满足请求时进入就绪状态等待系统调用
- 终止状态:进程结束,或出现错误,或被系统终止,进入终止状态。无法再执行
状态之间转换六种情况
运行——>就绪:1,主要是进程占用CPU的时间过长,而系统分配给该进程占用CPU的时间是有限的;
2,在采用抢先式优先级调度算法的系统中,当有更高优先级的进程要运行时,该进程就被迫让出CPU,
该进程便由执行状态转变为就绪状态
就绪——>运行:运行的进程的时间片用完,调度就转到就绪队列中选择合适的进程分配CPU
运行——>阻塞:正在执行的进程因发生某等待事件而无法执行,则进程由执行状态变为阻塞状态,如
发生了I/O请求
阻塞——>就绪:进程所等待的事件已经发生,就进入就绪队列
以下两种状态是不可能发生的:
阻塞——>运行:即使给阻塞进程分配CPU,也无法执行,操作系统在进行调度时不会从阻塞队列进行
挑选,而是从就绪队列中选取
就绪——>阻塞:就绪态根本就没有执行,谈不上进入阻塞态
进程更多的状态:
- 运行态:running
- 就绪态:ready
- 睡眠态:分为两种,可中断:interruptable,不可中断:uninterruptable
- 停止态:stopped,暂停于内存,但不会被调度,除非手动启动
- 僵死态:zombie,僵尸态,结束进程,父进程结束前,子进程不关闭,杀死父进程可以关闭僵死态 的子进程
4.进程使用内存的问题列举
内存泄漏:Memory Leak
指程序中用malloc或new申请了一块内存,但是没有用free或delete将内存释放,导致这块内存一直处于占用状态
内存溢出:Memory Overflow
指程序申请了10M的空间,但是在这个空间写入10M以上字节的数据,就是溢出,类似红杏出墙
内存不足:OOM
OOM 即 Out Of Memory,“内存用完了”,在情况在java程序中比较常见。系统会选一个进程将之杀死,在日志messages中看到类似下面的提示
Jul 10 10:20:30 kernel: Out of memory: Kill process 9527 (java) score 88 or sacrifice child
当JVM因为没有足够的内存来为对象分配空间并且垃圾回收器也已经没有空间可回收时,就会抛出这个error,因为这个问题已经严重到不足以被应用处理)。
java程序会先启动JVM虚拟机,再在虚拟机上运行程序,所以会占用很多内存
遇到这种情况,有两种解决方案
- 限制java进程的max heap,并且降低java程序的worker数量,从而降低内存使用
- 给系统增加swap空间
5.线程(Thread)
线程是程序执行中一个单一的顺序控制流程,是程序执行流的最小单元,是处理器调度和分派的基本单位。一个进程可以有一个或多个线程,各个线程之间共享程序的内存空间(也就是所在进程的内存空间)。一个标准的线程由线程ID、当前指令指针(PC)、寄存器和堆栈组成。而进程由内存空间(代码、数据、进程空间、打开的文件)和一个或多个线程组成。
简单来说,线程是进程中的执行路径,共享进程的资源和地址空间,多个线程可以并行执行不同的任务。,实现程序的并发处理,是复制了一部分进程的代码,可以完成部分任务的真正执行者
6.进程和线程的区别
- 线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位
- 一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线
- 进程之间相互独立,但同一进程下的各个线程之间共享程序的内存空间( 包括代码段、数据集、堆等)及一些进程级的资源(如打开文件和信号),同理,某进程内的线程在其它进程不可见
- 线程上下文切换比进程上下文切换要快得多。
PS:可以通过pstree、prtstat 进程pid号、cat /proc/PID/status等命令来查看一个程序是单线程是多线程
7.进程管理
7.1 PS 查看进程当前状态的快照(静态查看进程)
ps ( process state),可以查看进程当前状态的快照,默认显示当前终端中的进程,Linux系统各进程的相关信息均保存在/proc/数字目录/status 下的文件中
支持三种选项:
- UNIX选项 如: -A -e
- GNU选项 如: --help
- BSD选项 如: a
查看静态的进程统计信息
- "ps aux" 可以查看系统中所有的进程;
- "ps -le" 可以查看系统中所有的进程,而且还能看到进程的父进程的 PID 和进程优先级;
- "ps -l" 只能看到当前 Shell 产生的进程;
常用选项
- a:显示当前终端下的所有进程信息,包括其他用户的进程。与“x”选项结合时将示系统中所有的进程信息。
- u:使用以用户为主的格式输出进程信息。
- x:显示当前用户在所有终端下的进程信息。
- -e:显示系统内的所有进程信息。
- -l:使用长(Long)格式显示进程信息。
- -f:使用完整的(Full)格式显示进程信
- k|--sort 属性 对属性排序,属性前加 - 表示倒序 ps aux k -%cpu
- o 属性… 选项显示定制的信息 pid、cmd、%cpu、%mem
示例:
###ps aux 查看系统中所有的进程
[root@localhost ~]#ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.2 194504 4940 ? Ss 06:05 0:02 /usr/lib/systemd/syste
root 2 0.0 0.0 0 0 ? S 06:05 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S 06:05 0:00 [ksoftirqd/0]
root 5 0.0 0.0 0 0 ? S< 06:05 0:00 [kworker/0:0H]
root 7 0.0 0.0 0 0 ? S 06:05 0:00 [migration/0]
root 8 0.0 0.0 0 0 ? S 06:05 0:00 [rcu_bh]
root 9 0.0 0.0 0 0 ? S 06:05 0:02 [rcu_sched]
root 10 0.0 0.0 0 0 ? S 06:05 0:00 [watchdog/0]
root 11 0.0 0.0 0 0 ? S 06:05 0:00 [watchdog/1]
....
##各字段含义
#USER该进程是由哪个用户产生的
#PID进程的 ID
#%CPU该进程占用 CPU 资源的百分比,占用的百分比越高,进程越耗费资源
#%MEM该进程占用物理内存的百分比,占用的百分比越高,进程越耗费资源
#VSZ该进程占用虚拟内存的大小,单位为 KB
#RSS该进程占用实际物理内存的大小,单位为 KB
#TTY该进程是在哪个终端运行的。 其中,tty1 ~ tty7 代表本地控制台终端(可以通过 Alt+F1 ~ F7 快捷键切换不同的终端),tty1~tty6 是本地的字符界面终端,tty7 是图形终端。 pts/0 ~ 255 代表虚拟终端,一般是远程连接的终端,第一个远程连接占用 pts/0,第二个远程连接占用 pts/1,依次増长。?代表和终端无关,系统进程
#STAT进程状态。常见的状态有以下几种:
`-D`:不可被唤醒的睡眠状态,通常用于 I/O 情况。
`-R`:该进程正在运行。
`-S`:该进程处于睡眠状态,可被唤醒。
`-T`:停止状态,可能是在后台暂停或进程处于除错状态。
`-W`:内存交互状态(从 2.6 内核开始无效)。
`-X`:死掉的进程(应该不会出现)。
`-Z`:僵尸进程。进程已经中止,但是还是占用硬件资源。
`-<`:高优先级(以下状态在 BSD 格式中出现)。
`-N`:低优先级。
`-L`:被锁入内存。
`-s`:包含子进程。
`-l`:多线程(小写 L)。
`-+`:进程位于后台`
#START该进程的启动时间
#TIME该进程占用 CPU 的运算时间,注意不是系统时间
#COMMAND产生此进程的命令名。
###ps -le 查看系统中所有的进程,而且还能看到进程的父进程的 PID 和进程优先级
[root@localhost ~]#ps -le
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 1 0 0 80 0 - 48626 ep_pol ? 00:00:02 systemd
1 S 0 2 0 0 80 0 - 0 kthrea ? 00:00:00 kthreadd
1 S 0 3 2 0 80 0 - 0 smpboo ? 00:00:00 ksoftirqd/0
1 S 0 5 2 0 60 -20 - 0 worker ? 00:00:00 kworker/0:0H
1 S 0 7 2 0 -40 - - 0 smpboo ? 00:00:00 migration/0
1 S 0 8 2 0 80 0 - 0 rcu_gp ? 00:00:00 rcu_bh
1 S 0 9 2 0 80 0 - 0 rcu_gp ? 00:00:02 rcu_sched
5 S 0 10 2 0 -40 - - 0 smpboo ? 00:00:00 watchdog/0
...........
##各字段含义
#F进程标志,说明进程的权限,常见的标志有两个: 1:进程可以被复制,但是不能被执行; 4:进程使用超级用户权限;
#S进程状态。具体的状态和"ps aux"命令中的 STAT 状态一致;
#UID运行此进程的用户的 ID;
#PID进程的 ID;
#PPID父进程的 ID;
#C该进程的 CPU 使用率,单位是百分比;
#PRI进程的优先级,数值越小,该进程的优先级越高,越早被 CPU 执行;系统定义不可以人为修改
#NI进程的优先级,数值越小,该进程越早被执行;可以人为修改
#ADDR该进程在内存的哪个位置;
#SZ该进程占用多大内存;
#WCHAN该进程是否运行。"-"代表正在运行;
#TTY该进程由哪个终端产生;
#TIME该进程占用 CPU 的运算时间,注意不是系统时间;
#CMD产生此进程的命令名;
###ps -l 查看到当前shell产生的进程
[root@localhost ~]#ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 17026 17022 0 80 0 - 29144 do_wai pts/2 00:00:00 bash
0 R 0 18506 17026 0 80 0 - 37235 - pts/2 00:00:00 ps
7.2 top 动态查看进程
区别与ps命令,top命令可以提供一个交互窗口,实时监控进程的运行情况,是一种动态查看,就像不停使用的ps命令
引申:还有一个htop是一种全面增强版的top但是需要安装,top不需要安装
选项:
- -d 秒数:指定 top 命令每隔几秒更新。默认是 3 秒
- -b:使用批次处理模式输出。一般和"-n"选项合用,用于把 top 命令重定向到文件中
- -n 次数:指定 top 命令执行的次数。一般和"-"选项合用。
- -p 进程PID:仅查看指定 ID 的进程
- -s:使 top 命令在安全模式中运行,避免在交互模式中出现错误。
- -u 用户名:只监听某个用户的进程
在 top 命令的显示窗口中,可使用如下按键,进行交互操作:
- ? 或 h:显示交互模式的帮助
- c:按照 CPU 的使用率排序,默认就是此选项。
- M:按照内存(memory)的使用率排序。
- N:按照 PID 排序
- T:按照 CPU 的累积运算时间排序,也就是按照 TIME+ 项排序。
- k:按照 PID 给予某个进程一个信号。一般用于中止某个进程,信号 9 是强制中止的信号
- r:按照 PID 给某个进程重设优先级(Nice)值。
- q:退出 top 命令
- z:彩色显示
- F:通过光标设置字段是否展示,以及展示顺序
示例:
[root@localhost ~]# top
top - 13:00:35 up 26 min, 1 user, load average: 0.48, 0.33, 0.22
Tasks: 155 total, 1 running, 154 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1867048 total, 1105264 free, 334332 used, 427452 buff/cache
KiB Swap: 5238780 total, 5238780 free, 0 used. 1310488 avail Mem
###以上前五行,我们算作第一部分,可以判断服务器的健康状态。如果 1 分钟、5 分钟、15 分钟的平均负载高于 1,则证明系统压力较大。如果 CPU 的使用率过高或空闲率过低,则证明系统压力较大。如果物理内存的空闲内存过小,则也证明系统压力较大。
#在压力较大时候,找出什么进程占用了系统资源。如果是不必要的进程,就应该结束这些进程;如果是必需进程,那么我们该増加服务器资源(比如増加虚拟机内存),或者建立集群服务器。
##第一行(任务队列信息)
top - 13:00:35 up 26 min, 1 user, load average: 0.48, 0.33, 0.22
# 13:00:35
系统当前时间up 26 min 系统的运行时间,本机己经运行 26分钟
# 1 users
当前登录了1个用户
# load average: 0.48, 0.33, 0.22
系统在之前 1 分钟、5 分钟、15 分钟的平均负载。如果 CPU 是单核的,则这个数值超过 1 就是高负载:如果 CPU 是四核的,则这个数值超过 4 就是高负载 (这个平均负载完全是依据个人经验来进行判断的,一般认为不应该超过服务器 CPU 的核数)
##第二行 进程信息
Tasks: 155 total, 1 running, 154 sleeping, 0 stopped, 0 zombie
# Tasks 155 total
系统中的进程总数
# 1 running
正在运行的进程数
# 154 sleeping
睡眠的进程数
# 0 stopped
停止(暂停)的进程数
# 0 zombie
僵尸进程数。如果不是 0,则需要手工检查僵尸进程
##第三行(CPU信息)
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
# %Cpu(s): 0.0 us
用户模式占用的 CPU 百分比
# 0.0 sy,
系统模式占用的 CPU 百分比
# 0.0 ni
改变过优先级的用户进程占用的 CPU 百分比
# 100.0 id
空闲 CPU 占用的 CPU 百分比
# 0.0 wa
等待输入/输出的进程占用的 CPU 百分比
# 0.0 hi
硬中断请求服务占用的 CPU 百分比
# 0.0 si
软中断请求服务占用的 CPU 百分比
# 0.0 st
st(steal time)意为虚拟时间百分比,就是当有虚拟机时,虚拟 CPU 等待实际 CPU 的时间百分比
##第四行(物理内存信息)
KiB Mem : 1867048 total, 1105264 free, 334332 used, 427452 buff/cache
# KiB Mem : 1867024 total
物理内存的总量,单位为KB
# 1105264 free:
空闲的物理内存数量
# 334332 used
已使用的物理内存数量
# 427452 buff/cache
作为缓冲的内存数量
##第五行
KiB Swap: 5238780 total, 5238780 free, 0 used. 1310488 avail Mem
# KiB Swap: 5238780 total
交换分区(虚拟内存)的总大小,单位KB
# 5238780 free
空闲交换分区的大小
# 0 used.
已使用的交换分区的大小
# 1310488 avail Mem
可用于进程下一次分配的物理内存数量
###第二部分
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 193700 6828 4048 S 0.0 0.4 0:01.91 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:00.01 ksoftirqd/0
5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
7 root rt 0 0 0 0 S 0.0 0.0 0:00.03 migration/0
8 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcu_bh
9 root 20 0 0 0 0 S 0.0 0.0 0:00.17 rcu_sched
10 root rt 0 0 0 0 S 0.0 0.0 0:00.03 watchdog/0
11 root rt 0 0 0 0 S 0.0 0.0 0:00.02 watchdog/1
12 root rt 0 0 0 0 S 0.0 0.0 0:00.01 migration/1
13 root 20 0 0 0 0 S 0.0 0.0 0:00.00 ksoftirqd/1
15 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/1:0H
16 root rt 0 0 0 0 S 0.0 0.0 0:00.02 watchdog/2
17 root rt 0 0 0 0 S 0.0 0.0 0:00.00 migration/2
18 root 20 0 0 0 0 S 0.0 0.0 0:00.00 ksoftirqd/2
20 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/2:0H
21 root rt 0 0 0 0 S 0.0 0.0 0:00.02 watchdog/3
#第二部分表头解析
# PID
进程的ID号
# USER
该进程所属的用户
# PR
priority 优先级,数值越小 优先级越高
# NI
nice 优先级,数值越小 优先级越高
# VIRT
该进程使用的虚拟内存的大小,单位为 KB
# RES
该进程使用的物理内存的大小,单位为 KB
# SHR
共享内存大小,单位为 KB
# S
进程状态
# %CPU
该进程占用 CPU 的百分比
# %MEM
该进程占用内存的百分比
# TIME+
该进程总共占用的 CPU 时间
# COMMAND
进程的命令名(进程文件、进程名称)
缓冲(buffer)和缓存(cache):
- 缓存(cache)是在读取硬盘中的数据时,把最常用的数据保存在内存的缓存区中,再次读取该数据时,就不去硬盘中读取了,而在缓存中读取。
- 缓冲(buffer)是在向硬盘写入数据时,先把数据放入缓冲区,然后再一起向硬盘写入,把分散的写操作集中进行,减少磁盘碎片和硬盘的反复寻道,从而提高系统性能。
简单来说,缓存(cache)是用来加速数据从硬盘中"读取"的,而缓冲(buffer)是用来加速数据"写入"硬盘的。
虚拟内存、常驻内存和共享内存:
VIRT:virtual memory usage虚拟内存
- 进程需要的内存大小,但并没有占满。
- 假如进程新申请100MB的内存,但实际只使用了50MB,那么它会增长100MB,而不是实际的50MB使用量。
- VIRT = SWAP + RES
RES:resident memory usage常驻内存
- 进程当前使用的内存大小,不包括swap。
- 包含其他进程的共享内存。
- 如果申请100MB的内存,实际使用50MB,它只增长50MB,与VIRT相反。
- RES = CODE + DATA
SHR:shared memory 共享内存
- 除了自身进程的共享内存,也包括其他进程的共享内存。
- 计算某个进程所占的物理内存大小公式:RES – SHR
7.3 prtstat 查看指定进程信息
格式:prtstat pid
7.4 pgrep 查看指定进程
格式:pgrep 选项
选项:
- -U 指定用户
- -l: 显示进程名
- -a: 显示完整格式的进程名
- -P +pid: 显示指定进程的子进程
7.5 pidof 根据进程名来找pid号
用于已知程序名但不知道pid号
格式:pidof 进程名
7.6 uptime 系统运行了多久时间
一般在家目录打这条命令
显示系统的运行时间、平均负载以及当前活动用户数等信息
root@localhost ~]#uptime
01:29:00 up 2:07, 6 users, load average: 0.00, 0.01, 0.05
当前时间 运行时间 登录用户
7.7 pstree 命令程序数
可以树形查看进程信息
格式:
pstreepidpstree用户名
选项:
- -a 显示启动每个进程对应的完整指令,包括启动进程的路径、参数等
- -p 显示PID
- -u 显示用户切换
- -T 不显示线程thread,默认显示线程
- -u 显示用户切换
- -H pid 高亮显示指定进程及其前辈进程
7.8 lsof 列举系统中已经被打开的文件
通过 lsof 命令,我们就可以根据文件找到对应的进程信息,也可以根据进程信息找到进程打开的文件。
格式:lsof 选项
选项:
- -c 字符串:只列出以字符串开头的进程打开的文件
- +d 目录名:列出某个目录中所有被进程调用的文件
- -u 用户名:只列出某个用户的进程打开的文件
- -p pid:列出某个 PID 进程打开的文件
lsof命令还常用于恢复误删文件,但仅限于有人还在使用的情况下
#查看被删除但正在使用的文件
[root@localhost data]#lsof |grep delete
cupsd 1144(pid) root 10r REG 253,0 2337 9381005 /etc/passwd+ (deleted)
#查看该文件(fd 是文件描述符)
[root@localhost data]#ll /proc/1144/fd
总用量 0
lr-x------. 1 root root 64 11月 29 11:26 0 -> /dev/null
lrwx------. 1 root root 64 11月 29 11:26 1 -> socket:[20288]
lr-x------. 1 root root 64 11月 29 11:26 10 -> /etc/passwd+ (deleted)
lrwx------. 1 root root 64 11月 29 11:26 11 -> socket:[24022]
lrwx------. 1 root root 64 11月 29 11:26 12 -> socket:[24023]
#导出该文件(恢复文件)
cat /proc/1144/fd/10
7.9 mpstat 显示CPU相关统计
[root@localhost ~]#mpstat
Linux 3.10.0-693.el7.x86_64 (localhost.localdomain) 2023年07月27日 _x86_64_ (4 CPU)
01时31分37秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
01时31分37秒 all 0.71 0.00 1.08 0.75 0.00 0.04 0.00 0.00 0.00 97.41
当前时间 用户空间 ni优先级 系统内核 盗取时间 系统空闲
盗取时间和虚拟化有关,盗取时间是非自愿地在物理 CPU 上等待其处理时间的时间百分比
#1秒 一次 看3次
[root@localhost ~]#mpstat 1 3
7.10 dstat 系统资源统计
dstat命令是一个用来替换vmstat、iostat、netstat、nfsstat和ifstat这些命令的工具,是一个全能系统信息统计工具。与sysstat相比,dstat拥有一个彩色的界面,在手动观察性能状况时,数据比较显眼容易观察;而且dstat支持即时刷新,譬如输入dstat 3即每三秒收集一次,但最新的数据都会每秒刷新显示。和sysstat相同的是,dstat也可以收集指定的性能资源,比如dstat -c即显示CPU的使用情况。
但是dsata程序需要安装yum install dstat -y
7.11 iostat提供更丰富的IO性能状态数据
格式:iostat 选项(可加可不加)
选项:
- -c 只显示CPU行
- -d 显示设备〈磁盘)使用状态
- -k 以千字节为为单位显示输出
- -t 在输出中包括时间戳
- -x 在输出中包括扩展的磁盘指标
[root@localhost ~]#iostat
Linux 3.10.0-693.el7.x86_64 (localhost.localdomain) 2023年07月27日 _x86_64_ (16 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.01 0.01 0.01 0.00 0.00 99.97
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 1.05 52.47 31.68 2535708 1531027
scd0 0.00 0.02 0.00 1050 0
dm-0 1.04 51.67 31.24 2497179 1509539
dm-1 0.12 0.13 0.40 6288 19380
7.12 free 查看内存信息
格式:free
选项:
- -h 人性化显示
- -m 以mb为单位来显示
一般就是free -h
示例:
[root@localhost etc]# free
total used free shared buff/cache available
Mem: 1867048 333960 1105212 9308 427876 1310644
Swap: 5238780 0 5238780
[root@localhost etc]# free -h
total used free shared buff/cache available
Mem: 1.8G 326M 1.1G 9.1M 417M 1.2G
Swap: 5.0G 0B 5.0G
[root@localhost etc]# free -m
total used free shared buff/cache available
Mem: 1823 326 1078 9 417 1279
Swap: 5115 0 5115
8.监控系统(虚拟)资源
8.1 vmstat 动态查看系统资源的使用状况
vmstat命令,是 Virtual Meomory Statistics(虚拟内存统计)的缩写,可用来监控 CPU 使用、进程状态、内存使用、虚拟内存使用、硬盘输入/输出状态等信息
格式:
vmstat选项刷新延时 刷新次数vmstat选项
选项:
- -fs : -f是显示从启动到目前为止,系统复制(fork)的程序数,此信息是从 /proc/stat 中的 processes 字段中取得的。 -s是将从启动到目前为止,由一些事件导致的内存变化情况列表说明。
- -S : 单位, 令输出的数据显示单位,例如用 K/M 取代 bytes 的容量。
- -d :列出硬盘有关读写总量的统计表。
- -p :分区设备文件名 查看硬盘分区的读写情况。
vmstat 选项 刷新延时 刷新次数示例:
[root@localhost ~]# vmstat 3 2 //每3秒刷新一次,共执行2次
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 0 1223600 2332 370860 0 0 109 9 207 219 4 6 90 1 0
2 0 0 1223652 2332 370856 0 0 0 6 276 242 6 7 86 0 0
##各字段含义
# procs
进程信息字段: -r:等待运行的进程数,数量越大,系统越繁忙。 -b:不可被唤醒的进程数量,数量越大,系统越繁忙。
# memory
内存信息字段: -swpd:虚拟内存的使用情况,单位为 KB。 -free:空闲的内存容量,单位为 KB。 -buff:缓冲的内存容量,单位为 KB。 -cache:缓存的内存容量,单位为 KB。
# swap
交换分区信息字段: -si:从磁盘中交换到内存中数据的数量,单位为 KB。 -so:从内存中交换到磁盘中数据的数量,单位为 KB。 这两个数越大,表明数据需要经常在磁盘和内存之间进行交换,系统性能越差。
# io
磁盘读/写信息字段: -bi:从块设备中读入的数据的总量,单位是块。 -bo:写到块设备的数据的总量,单位是块。这两个数越大,代表系统的 I/O 越繁忙。
# system
系统信息字段: -in:每秒被中断的进程次数。 -cs:每秒进行的事件切换次数。 这两个数越大,代表系统与接口设备的通信越繁忙。
# cpu
CPU信息字段: -us:非内核进程消耗 CPU 运算时间的百分比。 -sy:内核进程消耗 CPU 运算时间的百分比。 -id:空闲 CPU 的百分比。 -wa:等待 I/O 所消耗的 CPU 百分比。 -st:被虚拟机所盗用的 CPU 百分比
通过分析 vmstat 命令的执行结果,可以获得一些与当前 Linux 运行性能相关的信息。比如说:
- r 列表示运行和等待 CPU 时间片的进程数,如果这个值长期大于系统 CPU 的个数,就说明 CPU 不足,需要增加 CPU。
- swpd 列表示切换到内存交换区的内存数量(以 kB 为单位)。如果 swpd 的值不为 0,或者比较大,而且 si、so 的值长期为 0,那么这种情况下一般不用担心,不用影响系统性能。
- cache 列表示缓存的内存数量,一般作为文件系统缓存,频繁访问的文件都会被缓存。如果缓存值较大,就说明缓存的文件数较多,如果此时 I/O 中 bi 比较小,就表明文件系统效率比较好。
- 一般情况下,si(数据由硬盘调入内存)、so(数据由内存调入硬盘) 的值都为 0,如果 si、so 的值长期不为 0,则表示系统内存不足,需要增加系统内存。
- 如果 bi+bo 的参考值为 1000 甚至超过 1000,而且 wa 值较大,则表示系统磁盘 I/O 有问题,应该考虑提高磁盘的读写性能。
- 输出结果中,CPU 项显示了 CPU 的使用状态,其中当 us 列的值较高时,说明用户进程消耗的 CPU 时间多,如果其长期大于 50%,就需要考虑优化程序或算法;sy 列的值较高时,说明内核消耗的 CPU 资源较多。通常情况下,us+sy 的参考值为 80%,如果其值大于 80%,则表明可能存在 CPU 资源不足的情况。
总的来说,vmstat 命令的输出结果中,我们应该重点注意 procs 项中 r 列的值,以及 CPU 项中 us 列、sy 列和 id 列的值。
vmstat 选项示例:
#显示从启动到目前为止,系统共派生的程序数
[root@localhost ~]# vmstat -f
54540 forks
9.进程的前后台管理
9.1进程的两种启动方式
- 前台启动:通过终端启动,且启动后一直占据终端
- 后台启动:可通过终端启动,但启动后即转入后台运行(释放终端)
9.2将进程放入后台的方法
1.命令+& 放入后台
- 运行中的作业: Ctrl+z 放到后台 但是会停止作业
- 尚未启动的作业: 命令(COMMAND) &(命令后加空格 &)
注意:第二种方式,命令后加空格 &,将程序放入后台会启动这个程序,使其在后台处于执行状态
放入后台执行的命令不能与前台有交互,否则这个命令是不能在后台执行的
2.jobs 查看后台任务列表
jobs+后台执行的命令 可以看到命令的列表 编号(第几个执行,也就是优先级)
3.fg 调出后台任务
fg+编号 把任务调回前台
4.bg 继续执行任务
bg+编号 重新开始后台任务
10.kill 结束进程
kill从字面来看,就是用来杀死进程的命令,但事实上,这个或多或少带有一定的误导性。从本质上讲,kill命令只是用来向进程发送一个信号,至于这个信号是什么,是用户指定的。
也就是说,kill命令的执行原理是这样的,kill命令会向操作系统内核发送一个信号(多是终止信号)和目标进程的 PID,然后系统内核根据收到的信号类型,对指定进程进行相应的操作。
kill是一个信号命令,可以通过这个命令来给进程传递信号,可以通过kill -l来查找使用需要的指令
格式:kill 信号 PID
需注意,kill命令是按照 PID 来确定进程的,所以kill命令只能识别 PID,而不能识别进程名。
列举一些常用信号:
- 0: EXIT 程序退出时收到该信息
- 1:HUP 挂掉电话线或终端连接的挂起信号,这个信号也会造成某些进程在没有终止的情况下重新初始化
- 2:INT 表示结束进程,但并不是强制性的,常用的 "Ctrl+C" 组合键发出就是一个 kill -2 的信号。
- 3:QUIT 退出
- 9:KILL 杀死进程,即强制结束进程
- 11:SEGV 段错误
- 15:TERM 正常结束进程,是 kill 命令的默认信号。
killall
killall 也是用于关闭进程的一个命令,但和 kill 不同的是,killall 命令不再依靠 PID 来杀死单个进程,而是通过程序的进程名来杀死一类进程,也正是由于这一点,该命令常与 ps、pstree 等命令配合使用
格式:killall 选项 信号 进程名
选项:
- -i:交互式,询问是否要杀死某个进程;
- -I:忽略进程名的大小写;
pkill
当作于管理进程时,pkill 命令和 killall 命令的用法相同,都是通过进程名杀死一类进程
格式:pkill 信号 进程名
pkill踢出登录用户
格式:pkill -t 终端号 进程名
选项:
- -U:根据进程所属的用户名终止相应进程
- -t:根据进程所在的终端终止相应进程
- -u uid: effective user,生效者
- -U uid: real user,真正发起运行命令者
- -t terminal: 与指定终端相关的进程
- -l: 显示进程名(pgrep可用)
- -a: 显示完整格式的进程名(pgrep可用)
- -P pid: 显示指定进程的子进程
PS:在踢出用户的时候,无论是kill PID还是killall都很容易误杀死进程,要么会把sshd服务杀死,要么会把自己的登录终端杀死,不过pkill命令不会出现这种问题,在踢出用户的时候,pkill命令是最优选择
示例:
#使用w命令查询本机已经登录的用户
w
#强制杀死从pts/1虚拟终端登陆的进程
pkill -9 -t pts/1
#查看张三用户
[root@localhost ~]#pgrep -l -u "zhangsan"
4491 bash
#强制杀死从pts/1虚拟终端登陆的进程
[root@localhost ~]#pkill -9 -t pts/1
[root@localhost ~]#pkill -9 -U zhangsan
[root@localhost ~]#pgrep -l -u "zhangsan"
二、计划任务
1.at 一次性任务
- 由包 at 提供
- 依赖与atd服务,需要启动才能实现at任务
- at队列存放在/var/spool/at目录中,ubuntu存放在/var/spool/cron/atjobs目录下
- 执行任务时PATH变量的值和当前定义任务的用户身份一致
at 命令的访问控制是依靠 /etc/at.allow(白名单)和 /etc/at.deny(黑名单)这两个文件来实现的,具体规则如下:
- 如果系统中有 /etc/at.allow 文件,那么只有写入 /etc/at.allow 文件(白名单)中的用户可以使用 at 命令,其他用户不能使用 at 命令(注意,/etc/at.allow 文件的优先级更高,也就是说,如果同一个用户既写入 /etc/at.allow 文件,又写入 /etc/at.deny 文件,那么这个用户是可以使用 at 命令的)。
- 如果系统中没有 /etc/at.allow 文件,只有 /etc/at.deny 文件,那么写入 /etc/at.deny 文件(黑名单)中的用户不能使用 at 命令,其他用户可以使用 at 命令。不过这个文件对 root 用户不生效。
- 如果系统中这两个文件都不存在,那么只有 root 用户可以使用 at 命令。
系统中默认只有 /etc/at.deny 文件,而且这个文件是空的,因此,系统中所有的用户都可以使用 at 命令。不过,如果我们打算控制用户的 at 命令权限,那么只需把用户写入 /etc/at.deny 文件即可。
1.1 at 一次性任务使用
格式:
at选项timeatHH:MMyyyy-mm-dd
示例:
#将命令"command"安排在当前时间过两小时执行
at now + 2 hours
at> command
at> CTRL+D
#将命令"command"安排在晚上10:30执行。
at 10:30 PM
at> command
at> CTRL+D
CTRL+D是提交任务
可以在at前加job [数字]给任务设定第几个执行(优先级)
选项:
| 格式 | 用法 |
|---|---|
| HH:MM | 比如 04:00 AM。如果时间已过,则它会在第二天的同一时间执行。 |
| Midnight(midnight) | 代表 12:00 AM(也就是 00:00)。 |
| Noon(noon) | 代表 12:00 PM(相当于 12:00)。 |
| Teatime(teatime)下午茶 | 代表 4:00 PM(相当于 16:00)。 |
| 英文月名 日期 年份 | 比如 January 15 2018 表示 2018 年 1 月 15 号,年份可有可无。 |
| MMDDYY、MM/DD/YY、MM.DD.YY | 比如 011518 表示 2018 年 1 月 15 号。 |
| now+时间 | 以 minutes、hours、days 或 weeks 为单位,例如 now+5 days 表示命令在 5 天之后的此时此刻执行。 |
1.2 查询和删除at任务
#查看at任务
[root@localhost ~]# atq
#删除指定的at任务
[root@localhost ~]# atrm [工作号]
2.crontab 周期任务
按照预先设置的时间周期(分钟、小时、天......)重复执行用户指定的命令操作。
主要设置文件。
- 全局配置文件,位于文件:/etc/crontab
- 系统默认的设置,位于目录:/etc/cron.*/
- 用户定义的设置,位于文件:/var/spool/cron/用户名
格式:crontab 选项 file
常用命令举例:
crontab-l-u 用户名:查看计划任务
crontab-e-u 用户名:编辑计划任务
crontab-r-u 用户名:删除计划任务
选项:
| 选项 | 功能 |
|---|---|
| -u user | 用来设定某个用户的 crontab 服务,例如 "-u demo" 表示设备 demo 用户的 crontab 服务,此选项一般有 root 用户来运行。 |
| -e | 编辑某个用户的 crontab 文件内容。如果不指定用户,则表示编辑当前用户的 crontab 文件。 |
| -l | 显示某用户的 crontab 文件内容,如果不指定用户,则表示显示当前用户的 crontab 文件内容。 |
| -r | 从 /var/spool/cron 删除某用户的 crontab 文件,如果不指定用户,则默认删除当前用户的 crontab 文件。 |
| -i | 在删除用户的 crontab 文件时,给确认提示。 |
如何使用crontab
crontab -e :创建或编辑当前用户的crontab
执行此命令后,会打开一个文本编辑器,编辑crontab文件 每行表示一个任务,可以使用cron表达式来定义执行时间,以及要执行的命令或脚本。
任务内容设置中,命令一定要用绝对路径,例如cp命令,要用/usr/bin/cp,可以用which查看命令的绝对路径
#进入 crontab 编辑界面。会打开Vim编辑你的任务
crontab -e
* * * * * command(执行的任务)
#每个*号的含义 含义 范围
第一个"*" 一小时当中的第几分钟(minute) 0~59
第二个"*" 一天当中的第几小时(hour) 0~23
第三个"*" 一个月当中的第几天(day) 1~31
第四个"*" 一年当中的第几个月(month) 1~12
第五个"*" 一周当中的星期几(week) 0~7(其中0和7都代表星期日)
简单记忆就是`分时日月周`
#在 crontab 编辑界面中有一些特殊符号
"*"(星号)代表任何时间
比如第一个"*"就代表一小时种每分钟都执行一次的意思。
","(逗号)代表不连续的时间。
比如"0 8,12,16***命令"就代表在每天的 8 点 0 分、12 点 0 分、16 点 0 分都执行一次命令。
"-“(中杠)代表连续的时间范围。
比如"0 5 ** 1-6命令",代表在周一到周六的凌晨 5 点 0 分执行命令。
"/"(正斜线)代表每隔多久执行一次。
比如"*/10****命令",代表每隔 10 分钟就执行一次命令。
#举例:
###每月的 1号 15号 30号
* * 1,15,30 * *
###中午 12点 - 16点
* 12-16/2 * * *
###每 半小时 执行 一次
30 * * * *
注意事项:
在书写 crontab 定时任务时,需要注意以下几个事项:
- 6 个选项都不能为空,必须填写。如果不确定,则使用
*代表任意时间。 - crontab 定时任务的最小有效时间是分钟,最大有效时间是月。像 2018 年某时执行、3 点 30 分 30 秒这样的时间都不能被识别。
- 在定义时间时,日期和星期最好不要在一条定时任务中出现,因为它们都以天为单位,非常容易让管理员混淆。
- 在定时任务中,不管是直接写命令,还是在脚本中写命令,最好都使用绝对路径。有时使用相对路径的命令会报错。