主要内容
进程
- 为什么引入进程? 最开始的操作系统是单道批处理的(一个程序处理完,再处理下一个程序)而IO是低速的,就会出现cpu要等待IO的情况;从而降低了实际效率。后来就引入多道批处理;而程序在执行的过程中又会因为共享资源而导致程序在执行的过程中相互限制;所有后来引入进程用来给程序提供一个抽象的概念,他能申请多道系统资源并且独立给程序提供资源,从而解决原来的程序之间因为资源共享而相互限制的问题。这样就可以提高系统资源的利用率以及系统的处理能力。引入进程模型,目的就是为了满足多道编程(程序的并发执行),而多道编程的目的就是为了提高cpu的利用率。随着进程数量的增加,cpu的利用率逐步提高。
- 进程概念 (1)进程是程序的一次执行。 (2)进程是可以和别的计算并发执行的计算。 (3)进程可定义为一个数据结构及能在其上进行操作的一个程序。 (4)进程是一个程序及其数据在处理机上顺序执行时所发生的活动。 (5)进程是程序在一个数据集合上的运行过程,是系统进行资源分配和调度的一个独立单位 (6)一个进程就是一个正在执行的程序,包括指令计数器、寄存器和变量的当前值。 综合以上观点, 进程(Process) 可以定义为“并发执行的程序在一个数据集合上的执行过程”。 可以更简单的认为。 进程=程序+执行。当把一个程序从磁盘中加载到内容中,cpu去运算和处理这个进程(运行起来的程序就是进程。
- 进程与程序的区别 进程是动态的,而程序是静态的。 进程的并发性和程序的顺序性。 进程是暂时的,而程序是可以永久保存的。 结构上进程是由进程控制块程序和数据构成的,而进程不是。
- 进程的组成 程序的代码 程序处理的数据 程序计数器中的值(下一条将运行指令的地址)一组通用的寄存器的当前值,堆,栈一组系统资源 进程控制块(Process contral Block)简称PCB.
- 进程具有的特征 动态性:进程是程序的一次执行过程,是临时的,有生命期的,是动态产生,动态消亡的; 并发性:任何进程都可以同其他进程一起并发执行; 独立性:进程是系统进行资源分配和调度的一个独立单位; 结构性:进程由程序、数据和进程控制块三部分组成。
进程控制块:
进程状态:就绪,运行,阻塞等。
程序计数器,CPU寄存器
CPU调度信息:进程优先级,调度队列等
内存管理信息:基地址,界限寄存器的值,页或段等。
记账信息:CPU使用时间,进程数量等。
IO状态信息
- 进程状态 新的(创建):进程正在创建,还没达到就绪态的地步。 就绪态:获得除了处理机使用权以外的所有机缘,等待使用处理机的状态。 运行态:程序在处理机上运行,单核CPU每个时刻只能有一个进程处于运行态,但是多个进程可以处于就绪或阻塞状态。 终止态:进程已经完成执行。 等待(阻塞态):进程可能以为需要某个资源而处于等待的状态,等待的是非处理机以外的其他资源。
- 进程的状态转换 创建态—>就绪态:当进程准备好一切的工作 就绪态—>运行态:进程得到了处理机的使用权 运行态—>就绪态:由于时间片用完,必须让出处理机使用权;或者有更高级的进程此时需要使用处理机 运行态—>阻塞态:由于进程需要请求使用某一资源,比如外设。这个时候进程会到达阻塞态去准备资源 阻塞态—>就绪态:进程所需要的资源准备完毕,此时只需要处理机使用权运行态—>结束态:进程运行完毕注意:由运行态到阻塞态是主动的,阻塞态到就绪态是被动的。比如进程需要某一个I/O设备,它会自己主动发出请求到阻塞态;这时会出现中断,处理机检测到了中断,就会执行中断程序,中断结束后,就被动的从阻塞态转变到就绪态。 状态转换图:
- 挂起状态 不同的操作系统,进程所处的状态个数是不同的。除了5中基本状态以为还引入其他状态。 挂起状态的引入: (1)内外存兑换的的需要:内存紧张时利用挂起进等待(阻塞)的进程调入外存。 (2)程序员调试的需要:调试程序时希望运行的进程停下来,利用挂起实现。 (3)负载调节:将不太紧急的进程挂起,先处理紧急的进程。 状态图:
状态转换:
阻塞=>阻塞挂起:内存不够时,将阻塞的进程调入外存。
阻塞挂起=>阻塞:释放够内存空间时,将进程从外存调入内存继续等待。
就绪→就绪挂起:当挂起一些阻塞的进程仍然不能满足内存的需要,或者当有高优
先级阻塞的进程和低优先级就绪的进程时,系统会选择首先挂起低优先级就绪的进程,因为系统认为应该让高优先级的进程尽快完成。
运行→就绪挂起:在抢占式分时操作系统中,当高优先级阻塞挂起的进程因事件出现而进人就绪挂起状态时,如果内存空间不够,系统可能将正在运行的进程状态转化为就绪挂起。
就绪挂起=>运行:系统没有进程时或者就绪挂起的进程优先级高于就绪的进程时。
进程的创建:
允许一个进程创建另一个进程。此时创建者称为父进程,被创建的进程称为子进程。子进程可以继承父进程所拥有的资源。当子进程被撤销时,应将其从父进程那里获得的资源归还给父进程。此外,在撤销父进程时,也必须同时撤销其所有的子进程。
在操作系统中,终端用户登录系统、作业调度、系统提供服务、用户程序的应用请求等都会引起进程的创建。操作系统创建一个新进程的过程如下(创建原语):
- 为新进程分配一个唯一的进程标识号,并申请一个空白的PCB(PCB是有限的)。若PCB申请失败则创建失败。
- 为进程分配资源,为新进程的程序和数据、以及用户栈分配必要的内存空间(在PCB 中体现)。注意:这里如果资源不足(比如内存空间),并不是创建失败,而是处于”等待状态“,或称为“阻塞状态”,等待的是内存这个资源。
- 初始化PCB,主要包括初始化标志信息、初始化处理机状态信息和初始化处理机控制信息,以及设置进程的优先级等。
- 如果进程就绪队列能够接纳新进程,就将新进程插入到就绪队列,等待被调度运行。 进程的终止: 进程的终止引起进程终止的事件主要有:正常结束,表示进程的任务已经完成和准备退出运行。 异常结束是指进程在运行时,发生了某种异常事件,使程序无法继续运行,如存储区越界、保护错、非法指令、特权指令错、I/O故障等。外界干预是指进程应外界的请求而终止运行,如操作员或操作系统干预、父进程请求和父进程终止。 操作系统终止进程的过程如下(撤销原语): 1.根据被终止进程的标识符,检索PCB,从中读出该进程的状态。 2.若被终止进程处于执行状态,立即终止该进程的执行,将处理机资源分配给其他进程。 3.若该进程还有子进程,则应将其所有子进程终止。 4.将该进程所拥有的全部资源,或归还给其父进程或归还给操作系统。 5.将该PCB从所在队列(链表)中删除。
- 进程切换 内核概念: 内核是计算机配置上的底层软件,是计算机功能的延伸。主要包含了与硬件关系紧密的模块,如时钟管理、中断处理、设备驱动等(处于最底层),以及运行频率较高的程序,如进行管理、存储器管理和设备管理等。
内核是利用原语来实现的。原语是由若干指令构成,是用于完成一定功能的过程。
对于通常的进程,其创建、撤销以及要求由系统设备完成的I/O操作都是利用系统调用而进入内核,再由内核中相应处理程序予以完成的。进程切换同样是在内核的支持下实现的,因此可以说,任何进程都是在操作系统内核的支持下运行的,是与内核紧密相关的。
进程切换是指处理机从一个进程的运行转到另一个进程上运行,这个过程中,进程的运行环境产生了实质性的变化。
切换过程:
- 保存处理机上下文,包括程序计数器和其他寄存器。
- 更新PCB信息。
- 把进程的PCB移入相应的队列,如就绪、在某事件阻塞等队列。
- 选择另一个进程执行,并更新其PCB。
- 更新内存管理的数据结构。
- 恢复处理机上下文。
- 线程为什么引入线程? 我们知道,为了提高CPU的效率,使程序并发执行,引入了进程的概念。但进程也有缺点: 1.进程只能在一个时间段内干一件事,如果相同时干两件事或多件事,进程则无法满足。 2.进程如果咋执行的过程中阻塞,整个进程就会挂起,进程将无法执行。 举个例子。web服务器要接收多个用户对图像声音视频使用的请求。一种方法就是使用单进程的方法,当服务器接受到新请求时创建另一个进程来处理,但是这样会消耗与原进程一样多的时间和资源。利用多线程实现,就不用再创建新的进程,线程基本消耗资源,那么此时只需要一个进程就能满足需求,大大提高了效率。 再简明写:上课为例。进程1这个学生,他比较专注,一次只能做一件事,要么只能听课,要么只能写字,要么只能思考。而进程2有多个线程,既可以听课,又可以写字和思考。如果老师讲课终止,那么听课的进程1就只能阻塞不能做其他事,而进程2能做笔记和思考。所以,引入线程后大大提高了上课的效率。 综上,我们知道,进程的目的是为了使多个程序并发执行,改善资源的利用率,而引入线程,是在进程的层次上提供了一层并发的抽象,减少了并发执行的时间和空间,使操作系统有更好的发挥。
- 进程和线程的比较 1.调度 在线程没有引入前,拥有资源的基本单位和独立调度及分配的基本单位都是进程。引入线程后,进程是资源分配的基本单位,线程是调度和分派的基本单位。 2.并发性 进程和线程都具有并发性,可以并发执行。 3资源 .进程是拥有资源的独立单位,线程一般不拥有自己的资源。但是线程可以共享进程资源。例如,进程通过调度可以从处理器获得资源,而线程只能访问该进程里的资源。 4.系统开销 创建和撤销进程都需要回收或分配资源,所以进程创建和撤销的时间大于线程。
- 线程的实现 用户级线程 用户级线程只存在用户级,与内核无关,内核不知道这种线程的存在。
内核级线程
系统的调度是基于线程的,也就是说,处理记得切换是以线程为单位进行的。
调度的区别 用户级线程:由于内核不知道该线程的存在,所以,在系统眼里只有进程,即一个多线程的进程,只能一次在一个核心运行。假设一个进程有两个用户级线程A,B,进程A运行时,进程B不能运行,只能等待A进程执行完才能执行B.如果进程A阻塞,那么系统就会认为整个进程就被阻塞,进程里的其他线程就全部阻塞。
内核级线程:由系统内核调度线程,系统无需考虑该线程属于哪个进程。当进程中的一个线程被阻塞了,但是其他线程不会被阻塞,会继续执行其他线程。
比较 内核级线程克服了用户级线程的两个不足。首先,在多处理机环境中,内核可以同时把同一个进程的多个线程分配到多个处理机上;再者,如果进程中的一个线程被阻塞,内核可以调度一个进程的另一个线程执行。除此之外,内核级线程的另一个优点是内核本身也可以设计成多线程。
相对于用户级线程,内核级线程的主要缺点是,在同一个进程中把控制权从一个线程切换给另一个线程需要内核的状态转换(即用户态到核心态的转换),内核级线程切换的代价比用户级线程大得多。
线程池
假设有一个Web服务器的多线程程序。对于Web服务器程序来说, 每当服务器收到一个用户请求,它就创建一个线程来处理请求。这里有一个潜在的问题,如果用户的请求过多,将无法限制系统中并发执行的线程数量,无限制的线程会耗尽系统资源,如内存和CPU。解决这一问题的方法是使用线程池(ThreadPool) 。
线程池的主要思想是在进程开始时创建一定数量的线程,并放入池中等待。当服务器收到请求时,它会唤醒池中一个线程,并将要处理的请求传递给它。一旦线程完成了服务,它会返回池中再等待工作;如果池中没有可用的线程,那么服务器会一直等到有空线程为止
线程池的优点如下所述。
(1)用现有线程处理请求要比创建新线程快。
(2)线程池限制了可用线程的数量,这对那些不能支持大量并发线程的系统影响较明显
线程池中的线程数量由系统的CPU数量、物理内存大小和允许并发用户请求的期望值等因素决定。高级的线程池还可以动态调整线程的数量,当系统负荷低时可减低内存消耗。
附载二篇其他人的文章
对进程线程以及用户级线程和内核级线程总结的易于理解,借鉴 tobe的呓语:用户级线程和内核级线程,你分得清吗?zhuanlan.zhihu.com
我要去头条:【面试高频问题】线程、进程、协程zhuanlan.zhihu.com