操做系统是程序与硬件交互的中间层,现代操做系统将程序的一次执行抽象为进程和线程的概念。
进程做为资源分配的基本单位,线程做为执行的基本单位。
进程和线程其实就是操做系统程序自己实现控制一个程序运行的数据项描述
全部的程序都是面向语言进行开发的,而语言自己是面向操做系统的,线程是操做系统对程序一次运行的抽象
因此,全部的多线程编程模型,必然听从操做系统的大逻辑,必然是符合操做系统的对线程的抽象概念,操做系统在抽象之上提供了API供应用程序调用
简言之,应用程序的底层是借助于操做系统来完成多线程编程模型的,因此怎么可能逾越系统这一根本?
本篇对操做系统中线程进程相关概念进行简单介绍
进程
在好久好久以前的串行执行时,程序按顺序加载到计算机中并运行,程序独占计算机的全部资源
程序具备顺序性,封闭性和可重现性
多道程序出现以后,程序须要并发的执行,计算机的资源是共享的,而再也不是某一程序运行后独享
因此再也不是顺序的,而是间断的,也再也不是封闭,也再也不具备可重现性
仍是以作饭为例,当只有你一我的使用厨房时,你能够随便;
可是当多我的共享时,若是你还把你本身切了一半的菜扔到那边,可能会被扔掉,可能会被用掉,固然也可能没事。
为了解决程序并发执行的问题,进程的概念被抽象出来,其实就至关于“一个厨房使用规章”被制定出来
因此说进程和线程就是操做系统用来管理维护一个程序的运行于切换而设计出来的一个概念,而后经过各类数据结构以及值等实现描绘出来
进程实体
一个程序的运行主要下面几个部分的数据
- 进程自己的信息(如今谁在用厨房?如今盆盆罐罐都被你放了什么?)
- 可执行的代码是哪些?(菜谱步骤是什么?)
- 程序运行所须要的数据是什么?(食材是什么?佐料又是什么?)
程序段、数据段、PCB(Process Control Block)三部分构成了进程实体
进程特征
程序的并发运行与以前的串行顺序运行有了很大的变化,主要有下面几个特征
进程状态
基本状态
多人轮流使用厨房时,某一时刻的你究竟是作完饭了?仍是还在排队?仍是正在作?你会有一个状态用来表述你如今的这种状况
对于进程也有状态的概念
最基本的状态包括:
其中核心是:就绪、执行、阻塞
基本的状态切换以下
状态转变简介:
进程建立后,会建立PCB,以及相关的必须信息,而后就进入就绪状态,等待CPU的调度
一旦CPU对该进程调度执行,也就是该进程得到了时间片,那么就会进行执行
当时间片用完以后,若是任务尚未结束,那么就须要继续等待(好比你作饭须要5小时,然而每一个人只容许2小时,若是2小时你作不完,你必须让别人先作,你从新排队来)
若是一个正在执行的程序遇到了IO请求,这一般是比较耗时的,进程会进入阻塞状态
进入阻塞状态的进程一旦得到了想要的结果,好比IO完成,那么就再次进入就绪状态,等待CPU的临幸
挂起状态
有些系统中,还会有挂起状态,可能系统须要让正在执行的程序暂停下来,也多是资源不足了,将某些不重要的进程暂停。
挂起是更完全的暂停,能够认为挂起是“暂时被淘汰出内存的进程”
阻塞状态得到资源后会进入就绪状态,而一旦挂起,除非解除这个状态,不然他将一直暂停,被抛出运行以外
阻塞是由于某些缘由暂时不能被执行,挂起是直接将你暂停
当你作饭时等待水烧开,这就是阻塞,而若是是老大说咱们几我的先来,因而他们几个轮流使用,而后你站门口看着,这就是挂起
包含挂起状态的系统基本状况如上图所示
就绪状态挂起后称之为静态就绪,阻塞状态挂起后称之为静态阻塞,挂起后的状态不可以直接转换到执行状态
活动状态通过挂起转换为静止状态,静止状态通过激活转换为活动状态
活动就绪与静止就绪经过挂起和激活转换;活动阻塞与静止阻塞经过挂起和激活转换;
活动就绪的状态通过进程调度得到CPU时间片,进入执行状态,执行状态遇到请求IO等阻塞操做进入活动阻塞状态,活动阻塞状态IO完成将会进入活动就绪状态,继续等待被CPU临幸,如上图蓝色三角区域
看起来复杂其实也很好理解,前提是要理解挂起的含义
好比资源不充足时,将一些不重要的进程暂时挂起,挂起是真正的暂停执行,是一种主动式的管理,阻塞则是被动的,挂起也意味着置换到外存中,而不是内存中
无论是活动阻塞仍是活动就绪,他们都在内存中,具有了相关条件,IO完成或者得到CPU时间片,就能够进行执行
挂起(静止)状态,静止阻塞仍是静止就绪,他们都是外存中,并不可以执行,他们还须要一个载入到内存的过程
一个静止阻塞的状态就至关于在外存中等待一个事件的完成,事件完成后,进入静止就绪状态,他此时仍是不会获得CPU的调度,激活后才有机会获得CPU临幸
存在挂起状态的系统,通过建立后,可能进入活动就绪,也可能进入静止就绪,并非必定进入活动就绪,而后再被挂起
在当前系统的性能和内存的容量均容许的状况下,完成对进程建立的必要操做后,相应的系统进程将进程的状态转换为活动就绪状态
考虑到系统当前资源情况和性能要求,并不分配给新建进程所需资源,主要是主存资源,相应的系统进程将进程状态转为静止就绪状态
终止状态的转换
终止状态一般是从执行状态进行转换,通常状况下无论一个什么状态的线程,他只有被执行时,才会可能进入终止状态
可是,在某些系统中,父进程有权利终止一个子进程,因此说这种状况下,就可能从阻塞或者就绪直接转换为终止状态
进程控制块
进程是对于程序执行的抽象描述,那么进程控制块,这个对进程的描述,就至关于进程的元数据,用于描述进程自己
尽管实现很复杂,可是咱们应该想象获得,操做系统内核都是C/C++,毕竟也只是一种编程语言,编程语言对于抽象概念的描述也只能是经过语言自己
因此说,他就是一个数据结构,记录了用于控制管理进程的各个数据项。
“PCB 中记录了操做系统所需的、用于描述进程的当前状况以及控制进程运行的所有信息。
进程控制块的做用是使一个在多道程序环境下不能独立运行的程序(含数据),成为一个能独立运行的基本单位,一个能与其它进程并发执行的进程。
或者说,OS是根据 PCB来对并发执行的进程进行控制和管理的
例如,当OS要调度某进程执行时,要从该进程的 PCB中查出其现行状态及优先级;
在调度到某进程后,要根据其 PCB 中所保存的处理机状态信息,设置该进程恢复运行的现场,并根据其 PCB 中的程序和数据的内存始址,找到其程序和数据;
进程在执行过程当中,当须要和与之合做的进程实现同步、通讯或访问文件时,也都须要访问 PCB;
当进程因为某种缘由而暂停执行时,又须将其断点的处理机环境保存在PCB中。
可见,在进程的整个生命期中,系统老是经过 PCB对进程进行控制的,亦即,系统是根据进程的PCB而不是任何别的什么而感知到该进程的存在的。
因此说,PCB是进程存在的唯一标志。 ”《计算机操做系统 第三版》
进程控制块主要包括:
- 进程标识符
- 计算机状态
- 进程调度信息
- 进程控制信息
进程用来管理程序运行,对于一个运行中的程序总归要有个名字,这就是进程标识符;
计算机运行时各个硬件设备寄存器保存的值就是计算机的状态(如同作饭时厨房盆盆罐罐里面的东西);
进程有状态,这些状态信息主要用来进行调度,也就是安排任务须要的信息(可能你长得好看,就能多一次机会使用厨房);
另外还有一些对进程的控制,好比进程(线程)同步数据、程序地址等
在一个系统中,一般可拥有数十个、 数百个乃至数千个 PCB。
为了能对它们加以有效的管理,应该用适当的方式将这些PCB组织起来。目前经常使用的组织方式有如下两种。
三座大山
进程做为操做系统对程序一次运行的抽象描述
进程的基本信息至关于元数据,就好像表结构同样以及一些必备的数据结构
对于进程的掌控主要有三座大山:
进程控制、进程同步、进程通讯
进程控制:
一个进程从无到有,须要建立,建立以后由于调度而运行,由于撤销而消亡,须要有人管理他们,进程基本信息好比PCB从哪里来?都须要有人去作,这部分工做被称为进程控制
进程同步:
多进程并发执行,必然可能会出现竟态,好比同时访问某个共享资源,一个打印机不能同时打印语文和数学,因此必须作好顺序的调度,这部分的工做被称之为进程同步
进程通讯:
多进程并发运行,如何进行进程间的联系,如何传递数据?不一样计算机中的两个进程又是如何进行数据交互?这部分工做被称之为进程通讯
若是一个员工是一个进程,进程控制至关于人事、财务部门,负责招聘薪资考勤等。
进程同步至关于项目经理,负责项目中各人员的任务分配调度。
进程通讯就至关于一种工做方式、沟通形式,好比你给我一个SVN标签号而且告知我意图,我去库中检索指定标签修改的指定内容,就完成了一个任务的协做。
比喻或许不足够恰当,仅供我的理解。
总结
进程做为操做系统对程序执行的抽象,那么就使用了足够多的数据项对进程进行描述,全部的信息都是为了进程的管理、维护、调度、切换等
就好比你用一个数组以及一个栈顶标记来描述一个堆栈,以下图所示
数组a[]以及变量top就是使用数组对栈这种数据结构进行抽象描述的数据项,对于数据元素操做访问(入栈、出栈)限制就是规则
进程看似复杂,原理也是如此,操做系统使用多个数据项(数据结构)对程序的执行进行描述,而后定义了一整套的操做逻辑与规则
这就是咱们如今学习的进程的运行原理
经过编码将设计思路以及运行规则从抽象到具体数据结构以及编码的实现就完成了进程的实现。
操做系统想要管理程序的运行,须要指定一个惟一的标识符,既然放一群羊,还想对羊进行合理的管理识别,最简单的办法就是每只羊挂个项圈写上序号。
进程有状态信息,操做系统负责管理状态的切换,那么必然须要记录进程的状态信息
既然是轮流分配时间片,就好像去办理业务,排队等待同样,可是无数个场景下都有VIP的存在,进程也是,也有优先级的概念
计算机的程序最终会转换为一条条的指令,每一条指令的执行都须要借助于程序计数器,程序计数器是用于存放下一条指令所在单元的地址的地方,因此想要知道而且记住程序执行的进度位置,还须要掌握程序计数器的值
咱们熟悉的x86和arm指令大多都是基于寄存器的(虚拟机VM是基于栈)基于寄存器的架构最明显的特征就在于指令的执行要依赖寄存器,如同厨房的盆盆罐罐,里面装着运行时的状态数据、值(比如计算1+2+3+4,1放到a寄存器,2放到b寄存器,add a,b 计算中间结果,这句纯属为了说明,具体不要较真)
想要更好地管理进程,那么必然还会有一些统计信息,好比某进程运行了多久等记录统计信息
这些重要的信息都保存在进程的PCB中,因此说PCB是进程概念的核心,有了PCB程序才有并发执行的能力,一般,一般状况下,建立进程指的就是建立PCB
简言之,操做系统对进程的抽象就是对于一组数据结构以及操做这些数据结构的规则逻辑的实现。
进程的核心状态有执行、就绪、阻塞。
就绪就是一切准备稳当,能够被执行,就差CPU时间片了,在执行过程当中若是时间片用完,那么仍旧是转换为就绪状态,他什么都不差,只是被剥夺了时间片
执行状态下,若是执行不下去了,好比须要等待IO,就会进入阻塞,阻塞必需要等到要等的事情发生才会解除阻塞,由于他差一个事件的发生和时间片,事件到达就解除阻塞,因此就差时间片了,因此转换为就绪状态
好比你去银行办业务,人家手续都带好了在那边排队就是就绪,你身份证没复印好,就得先复印好身份证再过来排队,不然即便到你了,你也办不成
就绪涉及到不少事情要处理,因此为了更加安全合理,有了建立的状态,建立就是为了保障就绪是真的就绪了,也就是检查你的确各类资料都带齐全了
终止状态也是相似为了更合理安排管理,结束后也有一些事情须要作,好比你把你的资料状态或者还可能要排队领取个什么别的东西,这些都不须要在柜台了,在大厅自助或者找大堂经理就行了
进程涉及到各类数据结构,各类规则处理,因此进程很复杂,可是进程又很简单,就比如单例模式的实现有多种方式有些比较复杂,可是逻辑上却又很清晰,保证惟一