基础知识
进程
内核的功能和作用:文件系统管理、网络管理、进程管理、内存管理等,属于linux最基础的功能 进程:process,正在运行中的程序的一个副本。允许有多个进程同时执行。 #操作系统负责分配cpu运行进程的顺序和时间 #副本:把磁盘上的指定文件加载到内存进行运行 运行多次就会有多个副本 #多实例:一个程序生成多个副本,每个副本在内存中独立运行 #进程是资源使用的分配单位,进程存在声明周期 #PID:进程的唯一标号 进程创建过程: #进程的父子关系:写实复制 1. 操作系统启动的时候有个总进程(系统的第一个进程):centos6--init centos7及以上--systemd 2. 后续的所有进程都是总进程生成的,一次推类,构成一个树状结构,c语言使用fork()函数创建子进程 #父进程创建子进程的过程: 父进程在内存中占有一片空间,创建子进程的时候,此时子进程用的内存空间是父进程那一块空间。当子进程产生数据更新以后,就会复制父进程的空间来作为自己独立的空间。
线程
线程:进程是系统资源分配的单位。进程在处理数据的时候,通过线程来完成任务。 #进程相当于一个组织,线程就相当于这个组织里面干活的员工。进程和线程是包含关系,多个线程共享进程的空间。 #线程在运行的时候的执行顺序由操作系统决定 #一颗CPU同时只能执行一件事,他将时间切成很小的时间片,不同的时间片做不同的任务,所以就感觉在同时做多件事情(实际上是轮流执行程序的)。 使用 pstree -p 可以看到系统中的进程和线程。#只有一个线程后面就不显示了(后面没有花括号)。
协程
协程:一个协程就相当于一个函数。
进程、线程、协程的区别:
1.线程是程序执行的最小单位,进程是操作系统分配资源的最小单位; 2.一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线 3.进程之间相互独立,但同一进程下的各个线程之间共享程序的内存空间
进程的结构
-
任务列表
-
PCB
任务列表
任务列表:操作系统允许运行多个进程,进程之间构成了一个进程列表(任务列表),所有进程都放在里面的。
PCB
PCB:存放一个具体进程的全部信息(包括进程编号、状态、优先级等),因为系统有多个进程,所以就存在多个PCB,每个PCB之间通过指针变量关联
页(Page)
页:进程内存资源的分配的最小单位,类似于文件系统的block,页的默认大小也是4k
虚拟地址和物理地址
-
虚拟地址
-
物理地址
虚拟地址
虚拟地址:存放相对地址,位置是变化的。不是固定的。
应用程序看到的是虚拟地址
物理地址
物理地址:具体的一个固定地址
MMU
MMU:内存管理单元(cpu中的硬件芯片),把虚拟地址转换成物理地址。
进程访问某个数据的时候,先把请求发送给操作系统,操作系统再交给cpu,cpu计算为物理地址,然后才能得到真正的数据。
tlb
tlb:缓存虚拟地址和物理地址的区域
内存的分配空间
-
用户空间:进程虚拟内存空间
-
内核空间:操作系统使用的
每个进程都包括5种不同的数据段
-
代码段
-
数据段
-
BSS段
-
栈
-
堆
代码段:存放可执行文件的操作指令 数据段:存放初始化了的全局变量 BSS段:存放未初始化的全局变量 #Block Started by Symbol”的缩写,意为“以符号开始的块 栈:存放临时变量(比如函数里面使用的变量) #先进后出 队列就是先进先出 堆:存放数组、对象
进程使用内存问题
-
内存泄漏
-
内存溢出
内存泄露: Memory Leak,分配的空间不释放,一直占用着 内存溢出:Memory Overflow,程序申请的空间不够用。 内存不足:OOM,内存不够用(java中的一种提示)
进程运行的状态
-
创建
-
就绪:
-
执行
-
终止
-
阻塞
使用 ps aux 可以看到进程的状态
进程更多的状态:
运行态:running #正在运行 就绪态:ready 睡眠态:进程不干活了,可中断:interruptable,不可中断(不能人为打断):uninterruptable 停止态:stopped,进程处于暂停的状态 僵死态:zombie,僵尸态,结束进程,父进程结束前,子进程不关闭,杀死父进程可以关闭僵死 态的子进程(这种进程不占用空间) #结束僵尸态的方法:把它的父进程杀死就没了或者恢复父进程
LRU 算法
LRU:Least Recently Used 近期最少使用算法(喜新厌旧),用来实现内存的充分利用
IPC 进程之间的通信
IPC: Inter Process Communication
通信方法:
-
同主机
-
跨主机
同一主机上:
-
管道
-
套接字
-
文件映射
-
共享内存
-
信号
管道:cmd1 | cmd2 (管道符的两边就开启了两个进程),单工通信 # | 这属于匿名管道 #命名管道:创建一个管道(pipe)文件,用来实现两个进程之间的通信。 A--->管道文件--->B #创建管道文件的命令:mkfifo(fifo:先进先出) #格式: mkfifo pipe_name 套接字:进程之间双向通讯 #查看套接字的方法:find / -type s -ls 文件映射:文件的数据映射到内存的一块空间中,多个进程共享这块内存空间 共享内存:直接在内存中分配一块空间,这块空间大家都能使用。 信号:trap -l 可以查看。发个信号进程收到以后就会按照指定的功能来进行操作。
跨主机通信:
socket:socket就是ip加上端口号。ip地址确定了设备在网络中的位置。端口号确定了设备上了具体应用程序。(使用tcp、udp协议都会分配要给与众不同的独有端口)
范例
范例:利用管道文件实现 IPC mkfifo /data/test.fifo #创建一个管道文件 ll /data/test.fifo #使用ll查看管道的信息,发现它的大小是0字节, cat > /data/test.fifo #输入123456 #在管道文件里面写入数据以后,不会自动退出,且此时文件的大小依然是0,以为这个管道文件是在内存里面的,不是在磁盘里面。 #在另一个终端可以从文件中读取数据 cat /data/test.fifo #会读取到123456
进程的优先级
系统优先级范围:0-139 0-9:实时优先级(一些特殊的系统进程) 100-139:非实时优先级(大部分进程使用的都是这个范围) #数字越小,优先级越高。
CentOS优先级:
nice数字范围:-20 -- +19 --对应系统优先级的100-139。 一般进程启动以后,优先级使用nice优先级的0 top显示的优先级是0-39,对应系统优先级的100-139
设置和调整进程优先级
进程分类
操作系统分类:
-
协作式多任务:
-
抢占式多任务:
协作式多任务:一个任务得到cpu后,只有它主动放弃cpu,其他进程才能使用 抢占式多任务:CPU的控制权由操作系统控制(由操作系统分配cpu资源)
进程类型
-
守护进程
-
前台进程
守护进程:daemon,计算机启动以后就自动运行,就和终端没关系了。 前台进程:跟终端相关,通过终端启动的进程
进程管理工具
pstree工具:
可以显示进程之间的父子关系
#格式: pstree [选项] [pid|user] #可以查看指定的进程信息,也可以查看所有的进程关系 #选项: -p:显示pid -T:不显示线程
ps工具:
作用:实现进程信息的查看,默认显示当前终端中的进程(显示的是当前瞬间的状态)
#ps默认显示的是当前终端中用户运行的进程列表。 Linux系统各进程的相关信息均保存在/proc/PID目录下的各文件中 #格式: ps [选项] #三种选项风格: UNIX选项 如: -A -e #单个字母 GNU选项 如: --help #完整单词 BSD选项 如: a #只需要一个字母 #常用选项: a 选项包括所有终端中的进程 u 显示每个进程是以谁的身份运行等信息 x 显示和终端有关或无关的进程(和终端无端:随计算机启动就启动了) o 属性… 显示指定的属性列 pid、cmd、%cpu、%mem -e 显示所有进程,相当于-A -f 显示完整格式程序信息 -p pid 显示指pid的进程 -t ttylist 指定tty,相当于 t
ps命令的输出信息:
C : ps -ef 显示列 C 表示cpu利用率 VSZ: 操作系统承诺给进程的空间(虚拟内存占用空间) RSS: 操作系统实际给进程的空间(实际内存占用空间) TTY:所在的终端,如果是?号表示和终端无关 STAT:进程状态 R:running #正在运行中的 S: interruptable sleeping #可中断的睡眠 D: uninterruptable sleeping #不可中断睡觉 T: stopped #停止 Z: zombie #僵尸 +: 前台进程 l: 多线程进程 L:内存分页并带锁 N:低优先级进程 <: 高优先级进程 s: session leader,会话(子进程)发起者 I:Idle kernel thread,CentOS 8 新特性 ni: nice优先级,nice值 #范围-20 --- 19 对应:100-139 pri: priority 系统优先级数字 #数字越大,优先级越高 rtprio: 实时优先级 #对应系统0-99 psr: processor 显示进程和cpu之间的绑定关系 #进程在那颗cpu上运行
范例
#ps -ef #unix风格 #ps aux #bsd风格 这个风格的选项显示的信息没有aux显示的要全 ##查看进程的特定属性 例如:#ps axo pid,cmd,%mem,%cpu #找到未知进程的执行程序文件路径 #ps命令显示的只是pid和程序的名称,没有显示程序的文件路径 ls -l /proc/1272/exe #1272表示进程的pid exe是一个软连接,指向程序的路径 #范例:查看优先级和CPU绑定关系 #ps axo pid,cmd,psr |grep 进程名
prtstat工具:
查看进程的信息
#格式 prtstat [选项] pid 例如:#prtstat 1026 [root@Centos8 ~]# prtstat 1026 Process: sshd State: S (sleeping) CPU#: 1 TTY: 0:0 Threads: 1 Process, Group and Session IDs Process ID: 1026 Parent ID: 1 Group ID: 1026 Session ID: 1026 T Group ID: -1 Page Faults This Process (minor major): 718 8 Child Processes (minor major): 80458 11 CPU Times This Process (user system guest blkio): 0.05 0.06 0.00 0.00 Child processes (user system guest): 93.69 11.96 0.00 Memory Vsize: 94 MB RSS: 7856 kB RSS Limit: 18446744073709 MB Code Start: 0x56188adb7000 Code Stop: 0x56188ae83f38 Stack Start: 0x7fffde7c3120 Stack Pointer (ESP): 0 Inst Pointer (EIP): 0 Scheduling Policy: normal Nice: 0 RT Priority: 0 (non RT)
查看某个进程的方法
- ps 选项 | grep 'pattern' #查找某个进程 - /sbin/pidof 按确切的程序名称查看pid - pgrep工具
pgrep
专门的进程过滤工具
命令格式: pgrep [options] pattern # 选项: -u uid: effective user,进程所有者 -U uid: real user,真正发起运行命令者 -t terminal: 与指定终端相关的进程 -l: 指定进程名 #根据进程名显示进程信息 -a: 显示完整格式的进程名 -P pid: 显示指定进程的子进程
pidof
知道程序名,用来获取进程pid。
格式:pidof process _name #选项: -x: 查找脚本的进程id #脚本必须shebang机制开头,以bash的方式来运行找不到,需要加权限来运行才找得到
uptime
系统负载信息查询
#和w命令、top命令最上面显示的信息也是一样的。 #显示信息 当前时间 系统已启动的时间 当前上线人数 系统平均负载(1、5、15分钟的平均负载,一般不会超过1,超过5时建议警报)
实时进程的查看:
-
htop工具
-
top工具
top工具
动态实时查看进程信息
#选项: -d # 指定刷新时间间隔,默认为3秒 -b 全部显示所有进程 -n # 刷新多少次后退出 -H 线程模式 #top命令显示的信息 us:用户空间 sy:内核空间 ni:调整nice时间 id:空闲 wa:等待IO时间 hi:硬中断 si:软中断(模式切换) st:虚拟机偷走的时间
htop工具
top工具的增强版。
#选项; -d #: 指定延迟时间; -u UserName: 仅显示指定用户的进程 -s COLUME: 以指定字段进行排序 #子命令 s:跟踪选定进程的系统调用 l:显示选定进程打开的文件列表 a:将选定的进程绑定至某指定CPU核心 t:显示进程树
CPU相关信息显示:mpstat工具
来源:sysstat包 显示信息说明: CPU: %usr:用户空间占用时间 %nice:nice优先级 %sys:系统内核占用时间 %iowait:io等待 %irq:中断 %soft:软中断 %steal:被虚拟机运行占用的时间 %guest:和虚拟化有关的 %gnice:虚拟机调整优先级 %idle:空闲的时间 PID(进程id) USER(进程发起者) PR(top里面的优先级) NI(nice优先级) VIRT(虚拟内存空间) RES(实际内存占用空间) SHR(共享内存占用空间) S(进程状态) %CPU(cpu利用率) %MEM(内存) TIME+(总的运行时间) COMMAND(对应的命令)
内存相关信息查看
free 可以显示内存空间使用状态
选项: -b 以字节为单位 -m 以MB为单位 -g 以GB为单位 -h 易读格式 -o 不显示-/+buffers/cache行 -t 显示RAM + swap的总和 -s n 刷新间隔为n秒 -c n 刷新n次后即退出
缓存的清理方法
向/proc/sys/vm/drop_caches中写入相应的修改值,会清理缓存 执行echo 1、2、3 至 /proc/sys/vm/drop_caches, 达到不同的清理目的
查看进程打开文件 lsof
lsof:list open files,列出正在打开的文件。
#选项: -a:列出打开文件存在的进程 -c<进程名>:列出指定进程所打开的文件 -g:列出GID号进程详情 -d<文件号>:列出占用该文件号的进程 +d<目录>:列出目录下被打开的文件 +D<目录>:递归列出目录下被打开的文件 -n<目录>:列出使用NFS的文件 -i<条件>:列出符合条件的进程(4、6、协议、:端口、 @ip ) -p<进程号>:列出指定进程号所打开的文件 -u:列出UID号进程详情 -h:显示帮助信息 -v:显示版本信息。 -n: 不反向解析网络名字
范例
查看某个端口是那个进程在使用 #查看所有正在打开的文件: lsof #找回被误删除的文件 前提是这个文件有人在访问 1. lsof | grep delete #过滤出被删除的文件,找到正在访问这个文件的进程编号 2. ll /proc/pid/fd #fd:文件描述符 3. cat /proc/pid/fd/文件描述符 > 导出为新文件
信号的管理
kill工具
用来向进程发送控制信号,以实现对进程管理,每个信号对应一个数字,信号名称以
SIG开头(可省略),不区分大小写
#显示当前可用的信号: trap -l kill -l #常用信号: 1) SIGHUP 无须关闭进程而重新加载配置文件 2) SIGINT 中止正在运行的进程;相当于Ctrl+c 3) SIGQUIT 相当于ctrl+ #退出进程 9) SIGKILL 强行关闭某个进程,可能会导致数据丢失(相当于按电源关机) 15) SIGTERM 正常关闭某个进程,默认信号 18) SIGCONT 继续运行 19) SIGSTOP 后台休眠 #信号的描述方法 数字法:1, 2, 9 全称:SIGHUP,sighup 简称 去掉开头的SIG,HUP,hup #向进程发送信号 通过pid的方式: kill [-s sigspec | -n signum | -sigspec] pid #-s sigspec:指定完整的信号名 #-n signum:信号的数字表示法 #-sigspec:信号的简写方法 #根据程序名发送信号 killall 程序名称 #0信号 信号为0,没有发送任何信号,仅仅检查进程是否正常工作。 格式: killall -0 程序名 例如: [root@centos8 ~]#killall -0 ping [root@centos8 ~]#echo $? 0
作业管理
-
前台管理
-
后台管理
前台运行管理:
前台:依赖一个终端,在某个终端运行,启动以后就占用这个终端,在这个终端里面就不能做其他的操作了
例如: ping 127.0.0.1
后台运行管理
后代:不占用终端资源,在进程执行的时候加一个&符号
例如:ping 127.0.0.1 &
前后台运行的切换
默认大多数命令是前台执行,前后台是可以切换的。
CTRL+C就是给前台执行的程序发送终止信号,快捷键支队前台执行的生效。对后台执行的程序无效。需要使用kill命令来发送信号
前--后台切换方法:
CTRL+Z快捷键 --- 把前台程序放到后台(放到后台以后程序就不运行了),通过bg 作业编号 --把后台停止的作业恢复成后台运行态 作业编号的查询:jobs命令 或者 kill -18 %作业编号
后台运行-->后台停止:
发送19信号: kill -19 %作业编号 作业编号:jobs命令
后--前切换方法;
fg 作业编号
后台执行的作用:
前台执行都是按照循序执行的,后台执行可以实现并行执行
后台执行的任务在终端关闭以后也会随之关闭。
实现窗口关闭还继续执行的方法;
方法一:screen命令 程序执行之前开启screen:格式:screen 然后再输入要执行的命令 方法二:nohup命令 格式:nohhup 要执行的程序 -- 会有输出的信息
并行执行的实现:
并行执行:让多个进程同时执行
方法一:把他们都放到后台去执行 方法二:(f1.sh&);(f2.sh&);(f3.sh&) --小括号括起来,分号隔开 方法三:f1.sh&f2.sh&f3.sh&
范例:扫描ip地址
net=10.0.0 for i in {1..254};do { if ping -c1 -W1 $net.$i &> /dev/null;then echo $net.$i is up else echo $net.$i is down fi }& #若里面有多个命令,就用花括号就是把它作为一个整体 done wait #后台执行的进程结束之后,主动退出