赞
踩
操作系统学习
【进程、线程、纤程】
【进程】
进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。、
当进程要从硬盘读取数据时,CPU 不需要阻塞等待数据的返回,而是去执行另外的进程。当硬盘数据返回时,CPU 会收到个中断,于是 CPU 再继续运行这个进程。
【并发和并行区别】
【进程的状态】
一般说来,一个进程并不是自始至终连续不停地运行的,它与并发执行中的其他进程的执行是相互制约的。它有时处于运行状态,有时又由于某种原因而暂停运行处于等待状态,当使它暂停的原因消失后,它又进入准备运行状态。所以,在一个进程的活动期间至少具备三种基本状态,即运行状态、就绪状态、阻塞状态。
运行状态(Running):该时刻进程占用 CPU;
就绪状态(Ready):可运行,由于其他进程处于运行状态而暂时停止运行;
阻塞状态(Blocked):该进程正在等待某一事件发生(如等待输入/输出操作的完成)而暂时停止运行,这时,即使给它CPU控制权,它也无法运行;
当然,进程还有另外两个基本状态:
创建状态(new):进程正在被创建时的状态;
结束状态(Exit):进程正在从系统中消失时的状态;
于是,一个完整的进程状态的变迁如下图:
NULL -> 创建状态:一个新进程被创建时的第一个状态;
创建状态 -> 就绪状态:当进程被创建完成并初始化后,一切就绪准备运行时,变为就绪状态,这个过程是很快的;
就绪态 -> 运行状态:处于就绪状态的进程被操作系统的进程调度器选中后,就分配给 CPU 正式运行该进程;
运行状态 -> 结束状态:当进程已经运行完成或出错时,会被操作系统作结束状态处理;
运行状态 -> 就绪状态:处于运行状态的进程在运行过程中,由于分配给它的运行时间片用完,操作系统会把该进程变为就绪态,接着从就绪态选中另外一个进程运行;
运行状态 -> 阻塞状态:当进程请求某个事件且必须等待时,例如请求 I/O 事件;
阻塞状态 -> 就绪状态:当进程要等待的事件完成时,它从阻塞状态变到就绪状态;
如果有大量处于阻塞状态的进程,进程可能会占用着物理内存空间,显然不是我们所希望的,毕竟物理内存空间是有限的,被阻塞状态的进程占用着物理内存就一种浪费物理内存的行为。
所以,在虚拟内存管理的操作系统中,通常会把阻塞状态的进程的物理内存空间换出到硬盘,等需要再次运行的时候,再从硬盘换入到物理内存。
那么,就需要一个新的状态,来描述进程没有占用实际的物理内存空间的情况,这个状态就是挂起状态。这跟阻塞状态是不一样,阻塞状态是等待某个事件的返回。
另外,挂起状态可以分为两种:
导致进程挂起的原因不只是因为进程所使用的内存空间不在物理内存,还包括如下情况:
除了链接的组织方式,还有索引方式,它的工作原理:将同一状态的进程组织在一个索引表中,索引表项指向相应的 PCB,不同状态对应不同的索引表。
一般会选择链表,因为可能面临进程创建,销毁等调度导致进程状态发生变化,所以链表能够更加灵活的插入和删除
【进程的控制】
01创建进程:
操作系统允许一个进程创建另外一个进程,而且允许子进程继承父进程所拥有的资源。
创建进程的过程:
查找需要终止进程的PCB;
如果出处于执行状态,则立即终止该进程的执行,然后将CPU资源分配给其他进程;
如果还有子进程,则应将该进程的子进程交给1号进程托管;
将该进程所拥有的全部资源都归还给操作系统;
将其从PCB队列里删除;
03阻塞进程:
当进程等待某一事件发生时,便会调用阻塞语句将自己阻塞,一旦阻塞,只能通过其他进程唤醒。
阻塞过程:
找到将要被阻塞进程标识符的PCB;
如果该进程为运行态,则保护现场,将其状态转换为阻塞态,停止运行;
将该PCB插入到阻塞队列
04唤醒进程:
进程由运行转换为阻塞状态,是由于必须等待某一事件的完成,所以阻塞的进程是不可能自己唤醒自己的。
如果某进程正在等待I/0事件,需由别的进程发消息给他,则只有该进程期待的事件发生时,才会由发现者进程用唤醒语句唤醒它。
唤醒过程:
在该事件的阻塞队列中找到该阻塞进程的PCB;
将其从阻塞队列中移除,并置其状态为就绪态;
把该PCB插入到就绪队列中,等待调度程序调度;
进程的阻塞和唤醒是一对功能相反的语句,如果某个进程调用了阻塞语句,则必定有一个对应的唤醒语句。
【进程的上下文切换】
各个进程是共享CPU资源的,在不同的时候进程之间需要进行上下文切换,让不同的进程在CPU上运行,所以,从一个进程切换到另一个进程运行,称为进程的上下文切换。
CPU上下文切换:
大多数操作系统都是多任务,通常支持大于 CPU 数量的任务同时运行。实际上,这些任务并不是同时运行的,只是因为系统在很短的时间内,让各个任务分别在 CPU 运行,于是就造成同时运行的错觉。
在每个任务运行前,CPU 需要知道任务从哪里加载,又从哪里开始运行。所以,操作系统需要事先帮 CPU 设置好 CPU 寄存器和程序计数器。
CPU 寄存器是 CPU 内部一个容量小,但是速度极快的内存(缓存)。我举个例子,寄存器像是你的口袋,内存像你的书包,硬盘则是你家里的柜子,如果你的东西存放到口袋,那肯定是比你从书包或家里柜子取出来要快的多。
程序计数器则是用来存储 CPU 正在执行的指令位置、或者即将执行的下一条指令位置。
所以说,CPU 寄存器和程序计数是 CPU 在运行任何任务前,所必须依赖的环境,这些环境就叫做 CPU 上下文(上下文是指某一时间点 CPU 寄存器和程序计数器的内容)
上下文切换可以认为是内核(操作系统的核心)在 CPU 上对于进程(包括线程)进行以下的活动:
挂起一个进程,将这个进程在 CPU 中的状态(上下文)存储于内存中的某处;在内存中检索下一个进程的上下文并将其在 CPU 的寄存器中恢复;跳转到程序计数器所指向的位置(即跳转到进程被中断时的代码行),以恢复该进程。根据任务的不同,把 CPU 上下文切换分成:进程上下文切换、线程上下文切换和中断上下文切换。
进程上下文切换:
进程是由内核进行管理和调度的,所以进程切换只能发生在内核态。
进程的上下文切换不仅包含了虚拟内存、栈、全局变量等用户空间的资源,还包括了内核堆栈、寄存器等内核空间的资源。
通常,会把交换信息保存在进程的PCB中,当要运行另外一个进程的时候,需要从这个进程的PCB中去除上下文,并加载到CPU中,使该进程可以被继续执行。
进程上下文切换是有开销的,所以我们希望进程可以把更多的时间花费在执行程序上,而不是花费在上下文切换。
进程上下文切换有哪些常见场景:
为了保证所有进程可以得到公平调度,CPU 时间被划分为一段段的时间片,这些时间片再被轮流分配给各个进程。这样,当某个进程的时间片耗尽了,进程就从运行状态变为就绪状态,系统从就绪队列选择另外一个进程运行;进程在系统资源不足(比如内存不足)时,要等到资源满足后才可以运行,这个时候进程也会被挂起,并由系统调度其他进程运行;当进程通过睡眠函数 sleep 这样的方法将自己主动挂起时,自然也会重新调度;当有优先级更高的进程运行时,为了保证高优先级进程的运行,当前进程会被挂起,由高优先级进程来运行;发生硬件中断时,CPU 上的进程会被中断挂起,转而执行内核中的中断服务程序;
【线程】
一个进程指的使正在执行的应用程序。线程的功能是执行应用程序中某个具体的任务,比如一段程序,一个函数。
即:操作系统中执行调度的基本单位。
【为什么要使用线程】
假设你要编写一个视频播放器软件,那么该软件功能的核心模块有三个:
从视频文件当中读取数据;
对读取的数据进行解压缩;
把解压缩后的视频数据播放出来;
对于单进程的实现方式,会是以下这个方式:
单进程存在的问题:
多进程存在的问题:
【线程的优缺点】
线程的优点:
n:1
n:m
具体可参考:用户线程、内核线程对应关系的三种模型_用户线程和内核线程的映射关系_weixin_42873905的博客-CSDN博客
用户级线程模型:
用户级线程的优点:
【僵尸进程和孤儿进程】
僵尸进程状态为:fefunct
杀掉僵尸进程必-须要把他的父进程干掉,因为只有他的父进程才能消掉僵尸进程的PCB,僵尸进程占用的资源也只有他的PCB,因为执行任务结束,所以其他的资源全都释放掉了。
进程类型:
【进程/线程之间是如何通信的】
【进程间通信】
管道 (使用最简单)、信号 (开销最小)、共享映射区 (无血缘关系)、本地套接字 (最稳定)
每个进程的用户地址空间都是独立的,一般而言是不能互相访问的,但内核空间是每个进程都共享的,所以进程之间要通信必须通过内核。
管道
linux中 " | " 就是一个管道,功能是将前一个命令的输出,作为后一个命令的输入
管道特性:
【进程调度】
Linux默认调度策略:
实时进程:优先级分高低 - FIFO(first in first out) 优先级一样 - RR(Round Robin
普通进程: CFS
【内存管理】
解决内存撑爆问题:分页:分块装入页框(内存页4K标准页)
分页:内存分成固定大小的页框(标准4K),把程序(硬盘上)分成4k大小的块需要哪块就装入哪块,当内存满时,最不常用的块将进入交换分区(swap),把最新的一块加载进来。这就是著名的LRU算法(最久未使用算法)。
内存管理底层结构:哈希表(保证查找操作O(1)) + 链表(保证排序和新增操作O(1))
虚拟内存:(解决相互打扰问题)
为保证相互不影响,让进程工作在虚拟空间,程序中用到的空间地址不再是直接的物理地址,而是虚拟地址,这样,A进程永远访问不到B进程的空间。
虚拟空间大小:寻址空间 - 64位操作系统(2^64),比物理空间大得多,单位是bit;
站在虚拟的角度,进程是独享整个系统+CPU
物理地址和虚拟地址的对应关系就叫地址映射
内存地址映射:偏移量+段的基地址=线性地址
【产生死锁的必要条件】
(1)互斥条件:进程要求对所分配的资源进行排它性控制,即在一段时间内某资源仅为一进程所占用。
(2)请求和保持条件:当进程因请求资源而阻塞时,对已获得的资源保持不放。
(3)不剥夺条件:进程已获得的资源在未使用完之前,不能剥夺,只能在使用完时由自己释放。
(4)环路等待条件:在发生死锁时,必然存在一个进程–资源的环形链。
【解决死锁的基本方法】
(1)资源一次性分配:一次性分配所有资源,这样就不会再有请求了:(破坏请求条件)
(2)只要有一个资源得不到分配,也不给这个进程分配其他的资源:(破坏请保持条件)
(3)可剥夺资源:即当某进程获得了部分资源,但得不到其它资源,则释放已占有的资源(破坏不可剥夺条件)
(4)资源有序分配法:系统给每类资源赋予一个编号,每一个进程按编号递增的顺序请求资源,释放则相反(破坏环路等待条件)
【进程的五大状态】
1)运行态(Running)。进程正在处理机上运行。在单处理机环境下,每个时刻最多只有一个进程处于运行态。
2)就绪态(Ready)。进程获得了除处理机外的一切所需资源,一旦得到处理机,便可立即运行。系统中处于就绪状态的进程可能有多个,通常将他们排成一个队列,称为就绪队列。
3)阻塞态(Waiting),又称等待态。进程正在等待某一事件而暂停运行,如等待某资源为可用(不包括处理机)或等待输入/输出完成。即使处理机空闲,该进程也不能运行。
4)创建态(New)。进程正在被创建,尚未转到就绪态。创建进程通常需要多个步骤:首先申请一个空白的PCB,并向PCB中填写一些控制和管理进程的信息;然后由系统为该进程分配运行时所必需的资源;最后把该进程转入就绪态。
5)结束态(Terminated)。进程正在从系统中消失,可能是进程正常结束或其他原因中断退出运行。进程需要结束运行时,系统首先必须置该进程为结束态,然后再进一步处理资源释放和回收等工作。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。