操作系统-cpu概念部分02-进程、线程、多线程、进程控制块PCB、进程间通信、死锁

发布于:2024-07-19 ⋅ 阅读:(304) ⋅ 点赞:(0)

操作系统-cpu概念部分02-进程状态–中断-CPU 的多级缓存-CPU性能优化

参考来源:
极客时间:Linux性能优化实战
极客时间:Linux实战技能100讲
summer课堂网规内部课件:补充02:操作系统
书籍:操作系统概念-第9版,第3~6章节

操作系统5大功能:

进程管理、存储管理、文件管理、设备管理、作业管理。

操作系统负责进程管理的以下活动
。在CPU上调度进程和线程
。创建和删除用户进程和系统进程
●挂起和重启进程
。提供进程同步机制
●提供进程通信机制

操作系统负责内存管理的以下活动:
。记录内存的哪部分在被使用以及被谁使用。
。决定哪些进程(或其部分)会调入或调出内存。
。根据需要分配和释放内存空间。

操作系统负责文件管理的以下活动:
·创建和删除文件。
·创建和删除目录,以便组织文件。
·提供文件和目录的操作原语。
·映射文件到外存。
·备份文件到稳定(非易失的)存储介质

操作系统负责有关硬盘管理的以下活动:
·空闲空间管理
·存储空间分配
·硬盘调度

操作系统的目的之一是为用户隐藏具体硬件设备的特性。例如,在UNIX系统中,I/O子系统(I/Osubsystem)为操作系统本身隐藏了I/O设备的特性。I/O子系统包括以下几个组件:
●包括缓冲、高速缓存和假脱机的内存管理组件。
·设备驱动器的通用接口。
·特定硬件设备的驱动程序。
只有设备驱动程序才能知道控制设备的特性。

PC和服务器端操作系统分类:Windows、Unix、Linux(开源)。
国产操作系统:UOS、麒麟、中科方德、深度、红旗。(都是基于Linux开发)
移动操作系统:IoS(苹果)、安卓(Android)和鸿蒙(HarmonyOS)

安卓操作系统四层架构

在这里插入图片描述

鸿蒙操作系统:

鸿蒙操作系统整体架构采用分层的层次化设计,从下向上依次为:内核层、系统服务层、框架层和应用层;
鸿豪操作系统内核层采用微内核设计,拥有更强的安全特性和低时延特点
鸿蒙操作系统架构采用了分布式设计理念,实现了分布式软总线、分布式设备虚拟化、分布式数据管理和分布式任务调度等四种分布式能力
架构的系统安全性主要体现在搭载HarmonyOS的分布式终端上,可以保证“正确的人,通过正确的设备,正确地使用数据”;

进程与线程

进程是一个具有一定独立功能的程序在一个数据集合上依次动态执行的过程,

进程和程序的区别
程序本身不是进程。程序只是被动(passive)实体,如存储在磁盘上包含一系列指令的文件(经常称为可执行文件(executablefile))。
相反,进程是活动(active)实体,具有一个程序计数器用于表示下个执行命令和一组相关资源。当一个可执行文件被加载到内存时,这个程序就成为进程。
进程还包括当前活动,如程序计数器(programcounter)的值和处理器寄存器的内容等。
另外,进程通常还包括:进程堆栈(stack)(包括临时数据,如函数参数、返回地址和局部变量)和数据段(datasection)(包括全局变量)。进程还可能包括(heap),这是在进程运行时动态分配的内存。
–来自书籍:《操作系统概念》3.1进程概念

■进程是一个正在执行的程序的实例,包括程序计数器、寄存器和程序变量的当前值
■进程有哪些特征?
:进程依赖于程序运行而存在,进程是动态的,程序是静态的
:每个进程拥有独立的地址空间,地址空间包括代码区、数据区和堆栈区,进程之间的地址空间是隔离的,互不影响。

线程被设计成进程的一个执行路径,同一个进程中的线程共享进程的资源,因此系统对线程的调度所需的成本远远小于进程。
一个进程可能包含多个线程,但一个线程只能属于一个进程。(集合中的包含关系,真子集)

进程的优先级和调整方法

在这里插入图片描述

降低nice  系统优先级

renice  -n 15

进程和线程的区别总结

本质区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位

■包含关系:一个进程至少有一个线程,线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。

资源开销:每个进程都有独立的地址空间,进程之间的切换会有较大的开销;线程可以看做轻量级的
进程,同一个进程内的线程共享进程的地址空间,每个线程都有自己独立的运行栈和程序计数器,线
程之间切换的开销小。

影响关系:一个进程崩溃后,在保护模式下其他进程不会被影响,但是一个线程崩溃可能导致整个进
程被操作系统杀掉,所以多进程要比多线程健壮

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

死锁

死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力
作用,它们都将无法推进下去。(三个和尚没水喝的故事,是在争夺啥呢?)

■死锁避免:指进程在每次申请资源时判断这些操作是否安全,典型避免死锁的算法是银行家算法
不产生死锁的条件:资源数≥并发进程数*(每个进程所需资源-1)+1,即n(m-1)+1。
在这里插入图片描述

进程状态

iowait 升高时,进程很可能因为得不到硬件的响应,而长时间处于不可中断状态。从 ps或者 top 命令的输出中,你可以发现它们都处于 D 状态,也就是不可中断状态
(Uninterruptible Sleep)。既然说到了进程的状态,进程有哪些状态你还记得吗?我们先来回顾一下。

top 和 ps 是最常用的查看进程状态的工具,我们就从 top 的输出开始。下面是一个 top
命令输出的示例,S 列(也就是 Status 列)表示进程的状态。从这个示例里,你可以看到
R、D、Z、S、I 等几个状态,它们分别是什么意思呢?
在这里插入图片描述
man top,查询进程状态信息
在这里插入图片描述
我们挨个来看一下:
R 是 Running 或 Runnable 的缩写,表示进程在 CPU 的就绪队列中,正在运行或者正在等待运行。
D 是 Disk Sleep 的缩写,也就是不可中断状态睡眠(Uninterruptible Sleep),一般表示进程正在跟硬件交互,并且交互过程不允许被其他进程或中断打断。
Z 是 Zombie 的缩写,如果你玩过“植物大战僵尸”这款游戏,应该知道它的意思。它表示僵尸进程,也就是进程实际上已经结束了,但是父进程还没有回收它的资源(比如进程的描述符、PID 等)。(僵尸进程、孤儿进程)
S 是 Interruptible Sleep 的缩写,也就是可中断状态睡眠,表示进程因为等待某个事件而被系统挂起。当进程等待的事件发生时,它会被唤醒并进入 R 状态。
I 是 Idle 的缩写,也就是空闲状态,用在不可中断睡眠的内核线程上。前面说了,硬件交互导致的不可中断进程用 D 表示,但对某些内核线程来说,它们有可能实际上并没有任何负载,用 Idle 正是为了区分这种情况。
要注意,D 状态的进程会导致平均负载升高, I 状态的进程却不会。

除了以上 5 个状态,进程还包括下面这2 个状态。

第一个是 T 或者 t,也就是 Stopped 或 Traced 的缩写,表示进程处于暂停或者跟踪状态。
向一个进程发送 SIGSTOP 信号,它就会因响应这个信号变成暂停状态(Stopped);再向
它发送 SIGCONT 信号,进程又会恢复运行(如果进程是终端里直接启动的,则需要你用
fg 命令,恢复到前台运行)。
而当你用调试器(如 gdb)调试一个进程时,在使用断点中断进程后,进程就会变成跟踪
状态,这其实也是一种特殊的暂停状态,只不过你可以用调试器来跟踪并按需要控制进程的
运行。
另一个是 X,也就是 Dead 的缩写,表示进程已经消亡,所以你不会在 top 或者 ps 命令
中看到它。

通过PS查看进程状态

针对STAT(进程当前状态)的描述如下:

D  无法中断的休眠状态(通常 IO 的进程)
R  正在运行可中在队列中可过行的
S  处于休眠状态
T  停止或被追踪
W 进入内存交换 (从内核2.6开始无效)
X  死掉的进程 (基本很少见)
Z  僵尸进程
<  优先级高的进程
N  优先级较低的进程
L 有些页被锁进内存
s  进程的领导者(在它之下有子进程)
l  多线程,克隆线程(使用 CLONE_THREAD, 类似 NPTL pthreads)
+  位于后台的进程组

–来自书籍:《操作系统概念》3.1.2进程状态
新的(new):进程正在创建
运行(running):指令正在执行。
等待(waiting):进程等待发生某个事件(如I/O完成或收到信号)。
就绪(ready):进程等待分配处理器。
终止(terminated):进程已经完成执行
在这里插入图片描述

进程控制块

操作系统内的每个进程表示,采用进程控制块(Process Control Block,PCB)也称为任务控制块(task control block)
一个PCB的例子。它包含许多与某个特定进程相关的信息:
·进程状态(processstate):状态可以包括新的、就绪、运行、等待、停止等。
·程序计数器(programcounter):计数器表示进程将要执行的下个指令的地址。
·CPU寄存器(CPUregister):根据计算机体系结构的不同,寄存器的类型和数量也会
不同。它们包括累加器、索引寄存器、堆栈指针、通用寄存器和其他条件码信息寄
存器。在发生中断时,这些状态信息与程序计数器一起需要保存,以便进程以后能
正确地继续执行(图3-4)。
·CPU调度信息(CPU-schedulinginformation):这类信息包括进程优先级、调度队列
的指针和其他调度参数。(第5章讨论进程调度)。
·内存管理信息(memory-managementinformation):根据操作系统使用的内存系统,
这类信息可以包括基地址和界限寄存器的值、页表或段表(第8章)。
·记账信息(accountinginformation):这类信息包括CPU时间、实际使用时间、时间
期限、记账数据、作业或进程数量等。
·I/O状态信息(I/Ostatusinformation):这类信息包括分配给进程的I/O设备列表、打
开文件列表等。
简而言之,PCB简单地作为这些信息的仓库,这些信息随着进程的不同而不同。
在这里插入图片描述

进程调度–上下文切换

切换CPU到另一个进程需要保存当前进程状态和恢复另一个进程的状态,这个任务称为上下文切换(contextswitch)。当进行上下文切换时,内核会将旧进程状态保存在其PCB中,然后加载经调度而要执行的新进程的上下文。上下文切换的时间是纯粹的开销,因为在切换时系统并没有做任何有用工作。上下文切换的速度因机器不同而有所不同,它依赖于内存速度、必须复制的寄存器数量、是否有特殊指令(如加载或存储所有寄存器的单个指令)。典型速度为几毫秒。
上下文切换的时间与硬件支持密切相关。

进程间通信-IPC(InterProcess Communication,IPC)机制,允许进程相互交互数据与信息。

进程间通信有两种基本模型:共享内存(shared memory)和消息传递(message passing)

共享内存模型会建立起一块供协作进程共享的内存区域,进程通过向此共享区域读出或写入数据来交换信息。

消息传递模型通过在协作进程间交换消息来实现通信。

同步与异步的概念

进程间通信可以通过调用原语send()和receive()来进行。实现这些原语有不
同的设计方案。消息传递可以是阻塞(blocking)或非阻塞(nonblocking),也称为同步
(synchronous)或异步(asynchronous)。

·阻塞发送(blocking send):发送进程阻塞,直到消息由接收进程或邮箱所接收。
·非阻塞发送(nonblocking send):发送进程发送消息,并且恢复操作。
·阻塞接收(blocking receive):接收进程阻塞,直到有消息可用。
·非阻塞接收(nonblocking receive):接收进程收到一个有效消息或空消息

在这里插入图片描述

提供环境允许进程协作,具有许多理由:
信息共享、计算加速、模块化、方便。

共享数据的并发访问有可能导致数据的不一致,讨论多种机制,确保共享同一逻辑地址空间的协作进程的有序执行,从而维护数据的一致性。

临界区问题,协作进程的同步问题

在这里插入图片描述
解决临界问题的方案,互斥锁、信号量,pass

死锁的概念

在这里插入图片描述

死锁的特征

在这里插入图片描述

死锁成立的四个必要条件

在这里插入图片描述

死锁处理方法

在这里插入图片描述

银行家算法的由来

在这里插入图片描述

无限阻塞或饥饿

在这里插入图片描述

进程组和会话

和进程相关的概念,进程组和会话。它们用来管理一组相互关联的进程,意思其实很好理解

进程组表示一组相互关联的进程,比如每个子进程都是父进程所在组的成员;(葫芦娃,一棵藤上七朵花)
会话是指共享同一个控制终端的一个或多个进程组。(窗口)

在这里插入图片描述

信号处理

在这里插入图片描述
在这里插入图片描述

中断

中断其实是一种异步的事件处理机制,可以提高系统的并发处理能力。(为什么会有中断?)

由于中断处理程序会打断其他进程的运行,所以,为了减少对正常进程运行调度的影响,中
断处理程序就需要尽可能快地运行。如果中断本身要做的事情不多,那么处理起来也不会有
太大问题;但如果中断要处理的事情很多,中断服务程序就有可能要运行很长时间。

软中断

事实上,为了解决中断处理程序执行过长和中断丢失的问题,Linux 将中断处理过程分成了两个阶段,也就
是上半部和下半部:(中断的处理过程是什么?会产生哪些问题?)

上半部用来快速处理中断,它在中断禁止模式下运行,主要处理跟硬件紧密相关的或时间
敏感的工作。
下半部用来延迟处理上半部未完成的工作,通常以内核线程的方式运行。

例子:
网卡接收到数据包后,会通过硬件中断的方式,通知内核有新的数据到了。这时,内核就应
该调用中断处理程序来响应它。你可以自己先想一下,这种情况下的上半部和下半部分别负
责什么工作呢?

上半部直接处理硬件请求,也就是我们常说的硬中断,特点是快速执行;
而下半部则是由内核触发,也就是我们常说的软中断,特点是延迟执行

查看软中断和内核线程

不知道你还记不记得,前面提到过的 proc 文件系统。它是一种内核空间和用户空间进行通
信的机制,可以用来查看内核的数据结构,或者用来动态修改内核的配置。其中:

/proc/softirqs 提供了软中断的运行情况;
/proc/interrupts 提供了硬中断的运行情况。

运行下面的命令,查看 /proc/softirqs 文件的内容,你就可以看到各种类型软中断在不同CPU 上的累积运行次数:

root@ub1804:/home/xiaoyue# cat /proc/softirqs | awk '{print $1,$2,$3,$4,$5,$6}'
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5
HI: 0 0 1 0 0
TIMER: 25139 29432 29631 30263 0
NET_TX: 95 1 0 814 0
NET_RX: 142 36 84 1670 0
BLOCK: 17386 38 11652 8494 0
IRQ_POLL: 0 0 0 0 0
TASKLET: 1 0 6 60 0
SCHED: 22073 23466 25268 22619 0
HRTIMER: 0 0 0 0 0
RCU: 27798 31718 32914 31307 0

$ cat /proc/softirqs
CPU0 CPU1
HI: 0 0
TIMER: 811613 1972736
NET_TX: 49 7
NET_RX: 1136736 1506885
BLOCK: 0 0
IRQ_POLL: 0 0
TASKLET: 304787 3691
SCHED: 689718 1897539
HRTIMER: 0 0
RCU: 1330771 1354737

在查看 /proc/softirqs 文件内容时,你要特别注意以下这两点

第一,要注意软中断的类型,也就是这个界面中第一列的内容。从第一列你可以看到,软中
断包括了 10 个类别,分别对应不同的工作类型。比如 NET_RX 表示网络接收中断,而NET_TX 表示网络发送中断

第二,要注意同一种软中断在不同 CPU 上的分布情况,也就是同一行的内容。正常情况下,同一种中断在不同 CPU 上的累积次数应该差不多。比如这个界面中,NET_RX 在CPU0 和 CPU1 上的中断次数基本是同一个数量级,相差不大

不过你可能发现,TASKLET 在不同 CPU 上的分布并不均匀。TASKLET 是最常用的软中断实现机制,每个 TASKLET 只运行一次就会结束 ,并且只在调用它的函数所在的 CPU 上运行。

软中断实际上是以内核线程的方式运行的,每个 CPU 都对应一个软中断内核线程,这个软中断内核线程就叫做 ksoftirqd/CPU 编号。那要怎么查看这些线程的运行状况呢?
其实用 ps 命令就可以做到,比如执行下面的指令:

root@ub1804:/home/xiaoyue# ps aux | grep softirq
root          9  0.0  0.0      0     0 ?        S    23:07   0:00 [ksoftirqd/0]
root         18  0.0  0.0      0     0 ?        S    23:07   0:00 [ksoftirqd/1]
root         24  0.0  0.0      0     0 ?        S    23:07   0:00 [ksoftirqd/2]
root         30  0.0  0.0      0     0 ?        S    23:07   0:00 [ksoftirqd/3]