一分钟明白进程,线程及线程安全和线程不安全,死锁
进程的概念
- 进程的起源和描述:在多道程序环境下,允许多个程序并发执行,此时它们将失去封闭性,并具有间断性及不可再现性的特征。为此引入了进程(Process)的概念,以便更好地描述和控制程序的并发执行,实现操作系统的并发性和共享性。
- 相应的数据结构:PCB
- PCB块的作用:使得上面提到的程序成为一个能独立运行的基本单位,也就是进程 ,可以与其他进程并发执行的进程;OS是根据PCB来对并发执行的进程进行控制和管理的。
- PDC块记录的内容有哪些: (首先有一些基本信息:例如进程名字,进程相对应的程序和数据的地址 ,进程拥有的资源清单;进程当前状态;关于进程调度的:进程优先级,进程调度时的cpu线程保护信息)
- 进程标识符 name:每个进程都必须有一个唯一的标识符,可以是字符串,也可以是一个数字。
- 进程当前状态 (新建态、终止态,运行态,就绪态,阻塞态(又称等待状态)):相同状态的进程会放在同一个队列中
- 进程相应的程序和数据地址,以便把PCB与其程序和数据联系起来。
- 进程资源清单。列出所拥有的除CPU外的资源记录,如拥有的I/O设备,打开的文件列表等。
- 进程优先级 priority:进程的优先级反映进程的紧迫程度,通常由用户指定和系统设置。
- CPU现场保护区 cpustatus:当进程因某种原因不能继续占用CPU时(如等待打印机),释放CPU,这时就要将CPU的各种状态信息保护起来,为将来再次得到处理机恢复CPU的各种状态,继续运行。
- 进程同步与通信机制 用于实现进程间互斥、同步和通信所需的信号量等
- 进程所在队列PCB的链接字 根据进程所处的现行状态,进程相应的PCB参加到不同队列中。PCB链接字指出该进程所在队列中下一个进程PCB的首地址。
- 与进程有关的其他信息。 如进程记账信息,进程占用CPU的时间等
- PCB工作实例:
例如,当OS要调度某进程执行时,要从该进程的PCB中查处其现行状态及优先级;在调度到某进程后,要根据其PCB中所保存的处理机状态信息,设置该进程恢复运行的现场,并根据其PCB中的程序和数据的内存始址,找到其程序和数据;进程在执行过程中,当需要和与之合作的进程实现同步,通信或者访问文件时,也都需要访问PCB;当进程由于某种原因而暂停执行时,又须将器断点的处理机环境保存在PCB中。可见,在进程的整个生命期中,系统总是通过PCB对进程进行控制的,即系统是根据进程的PCB而不是任何别的什么而感知到该进程的存在的。所以说,PCB是进程存在的唯一标志。
为了使参与并发执行的程序(含数据)能独立地运行,必须为之配置一个专门的数据结构,称为进程控制块(Process Control Block, PCB)。系统利用PCB来描述进程的基本情况和运行状态,进而控制和管理进程。相应地,由程序段、相关数据段和PCB三部分构成了进程映像(进程实体)。所谓创建进程,实质上是创建进程映像中的PCB;而撤销进程,实质上是撤销进程的PCB。值得注意的是,进程映像是静态的,进程则是动态的。
注意:PCB是进程存在的唯一标志!
从不同的角度,进程可以有不同的定义,比较典型的定义有:
进程是程序的一次执行过程。
进程是一个程序及其数据在处理机上顺序执行时所发生的活动。
进程是具有独立功能的程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。
在引入进程实体的概念后,我们可以把传统操作系统中的进程定义为:”进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位。“
进程的特征
进程是由多程序的并发执行而引出的,它和程序是两个截然不同的概念。进程的基本特征是对比单个程序的顺序执行提出的,也是对进程管理提出的基本要求。
动态性:进程是程序的一次执行,它有着创建、活动、暂停、终止等过程,具有一定的生命周期,是动态地产生、变化和消亡的。动态性是进程最基本的特征。
并发性:指多个进程实体,同存于内存中,能在一段时间内同时运行,并发性是进程的重要特征,同时也是操作系统的重要特征。引入进程的目的就是为了使程序能与其他进程的程序并发执行,以提高资源利用率。
独立性:指进程实体是一个能独立运行、独立获得资源和独立接受调度的基本单位。凡未建立PCB的程序都不能作为一个独立的单位参与运行。
异步性:由于进程的相互制约,使进程具有执行的间断性,即进程按各自独立的、 不可预知的速度向前推进。异步性会导致执行结果的不可再现性,为此,在操作系统中必须配置相应的进程同步机制。
结构性:每个进程都配置一个PCB对其进行描述。从结构上看,进程实体是由程序段、数据段和进程控制段三部分组成的。
- 进程是为了管理运行在计算机上的程序而抽象出的一种数据结构;
也就是说在多道程序环境下,多个程序并发执行时可以借助这个数据结构对程序的运行状态进行描述和控制;[1]
进程实体(进程映像)包括三部分:程序段,相关数据段和pcb段;
(Process Control Block, PCB)。系统利用PCB来描述进程的基本情况和运行状态,进而控制和管理进程。(在多道程序环境下,允许多个程序并发执行,此时它们将 失去封闭性,并具有 间断性 及不可再现性的特征。为此引入了进程(Process)的概念,以便更好地描述和控制程序的并发执行,实现操作系统的并发性和共享性。
)
- 进程状态:
线程
- 进程的起源和描述:线程的引入主要是为了提高并发性能,进程的调度往往开销是比较大的,所以将进程当作线程的一个容器,以进程作为操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位,也就是说线程是进程实际运行的实体,线程也有轻量级进程的说法;
- 线程的组成:线程ID、程序计数器、寄存器集合和堆栈组成。线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等。
- 由于同一进程的各线程间共享内存和文件资源,可以不通过内核进行直接通信 ,一个线程可以创建和撤销另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。
并行和并发:
线程安全:
线程安全就是在多线程编程中通过一些同步机制保证各个线程都可以正常且正确的执行;当然要回答好这个问题还得从它的反面线程不安全说起,那么什么是线程不安全呢? ——是指不提供加锁机制保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据
-
线程安全之所以成为问题是由于:
原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行
可见性:层次化存储,为了综合访问存储的速度、容量、价格,现代计算机通常采用 Cache、主存、外存的层次化存储。
重排序:为了提高 CPU 的吞吐率,通常会通过乱序技术把“无关”的指令在不同流水线上。(编译器,cpu,JIT)- 使用没有共享资源的模型
- 适用共享资源只读,不写的模型
- 不需要写共享资源的模型
- 使用不可变对象
- 直面线程安全(重点)
- 保证原子性
- 保证顺序性
- 保证可见性
-
让一个类或者函数线程安全有两种方法:
加锁,锁可以让乱序变的有序;锁还可以触发“回写”,让 Cache 和内存保持一致;
复制,每个线程一份数据,不共享数据;
死锁
进程的并发执行,改善了系统资源的利用率并提高了系统 的处理能力。然而,多个进程的并发执行也带来了新的问题——死锁。所谓死锁是指多个进 程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进。
死锁产生的必要条件
产生死锁的条件
必须同时满足以下四个条件,只要其中任一条件不成立,死锁就不会发生。
- 互斥条件:进程要求对所分配的资源(如打印机)进行排他性控制,即在一段时间内某 资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待。
- 不剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能 由获得该资源的进程自己来释放(只能是主动释放)。
- 请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源 已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。
*循环等待条件:存在一种进程资源的循环等待链,链中每一个进程已获得的资源同时被 链中下一个进程所请求。即存在一个处于等待状态的进程集合{Pl, P2, …, pn},其中Pi等 待的资源被P(i+1)占有(i=0, 1, …, n-1),Pn等待的资源被P0占有; - 解决死锁的策略
参考文献:
[1] C语言中文网 进程的概念