前言
本文将详细介绍进程
相关概念。
进程和程序
计算机上的未运行的QQ、Wechat等都属于程序,但是一旦当这些程序运行起来的话,就可以被称为进程。因此可以如下定义程序和进程:
程序:就是存在硬盘上的一堆代码。
进程:就是正在运行的程序。
程序就是一堆代码的集合,本身并没有任何意义,就是一堆静态文件,进程是程序的执行过程,是一个动态的过程,程序可以作为数据长期存在与硬盘上,但是进程是有一定生命周期的,因此程序是永久的,进程是暂时的。
同样一个程序运行两次,就会在操作系统中出现两个进程,虽然是同一个软件程序,但是可以做不同的事情,比如打开两个QQ,一个可以登陆自己的账号,另一个可以登陆男朋友的账号---查岗(O(∩_∩)O哈哈~),但是这两个进程之间是互不影响的。
进程调度算法
如果想要多个进程交替进行,操作系统就必须对这些进程进行调度,这种调度并不是随机的,而需要遵循一定的法则,由此就有了进程的调度算法。
先来先服务(FCFS)调度算法
用户首先执行哪个任务,这个任务就会一直占用CPU直至这个程序运行结束,后面想要执行的任务必须等上一个任务运行完成。这种算法对于长作业比较有利,对短作业就没有那么友好了。
短作业优先调度算法
哪个任务运行的时间短CPU就先运行哪个程序,但对长作业不利,不能保证紧迫性作业(进程)被及时处理;作业的长短只是被估算出来的。
时间片轮转法 & 多级反馈队列
时间片轮转的基本思路基本思路是让每个进程在就绪队列中的等待时间与享受服务的时间成比例。在时间片轮转法中,需要将CPU的处理时间分成固定大小的时间片,例如,几十毫秒至几百毫秒。如果一个进程在被调度选中之后用完了系统规定的时间片,但又未完成要求的任务,则它自行释放自己所占有的CPU而重新排队,等待下一次调度。同时,进程调度程序又去调度当前队列中的第一个进程。
前面介绍的各种用作进程调度的算法都有一定的局限性。如短进程优先的调度算法,仅照顾了短进程而忽略了长进程,而且如果并未指明进程的长度,则短进程优先和基于进程长度的抢占式调度算法都将无法使用。 而多级反馈队列调度算法则不必事先知道各种进程所需的执行时间,而且还可以满足各种类型进程的需要,因而它是目前被公认的一种较好的进程调度算法。在采用多级反馈队列调度算法的系统中,调度算法的实施过程如下图所述。
并发 & 并行
我们知道如果想让一个服务端同时对不同的客户端进行服务,该服务端就需要并发处理多个客户端的不同请求,而并发的核心就是单核CPU实现并发
,并发的概念马上就会介绍哦。
并行 & 并发
无论是并行还是并发,在用户看来都是同时运行
的,比如计算机上同时运行
QQ、微信、浏览器等,真正干活的是CPU,一个CPU同时只能执行一个任务。
并行:是指两个或者多个任务同时执行,比如鸣人有分身术,做饭和洗衣服两个任务可以同时执行,并行需要多个CPU。
并发:是伪并行,在资源有限比如只有单核的CPU的情况下,实现看起来是同时运行的效果,单核CPU + 多道技术就可以实现并发。
单道技术 & 多道技术
单道技术就是一个程序执行完毕才会执行下一个程序,如下图所示:
多道技术就是针对单核CPU实现并发,现在的主机一般是多核,那么每个核都会利用多道技术。内存中同时存入多道(多个)程序,cpu从一个进程快速切换到另外一个,使每个进程各自运行几十或几百毫秒,这样,虽然在某一个瞬间,一个cpu只能执行一个任务,但在1秒内,cpu却可以运行多个进程,这就给人产生了并行的错觉,即伪并发,以此来区分多处理器操作系统的真正硬件并行(多个cpu共享同一个物理内存)。因此多道技术就是CPU切换执行任务并保存任务执行状态。
进程运行的状态
一般说来,一个进程并不是自始至终连续不停地运行的,它与并发执行中的其他进程的执行相互制约。在一个进程的活动期间至少具备三种基本状态,即运行状态、就绪状态、阻塞状态。
1.当进程被创建完成并初始化后,会变成就绪状态。
2.处于就绪状态的进程被操作系统的进程调度器选中后,就分配给 CPU 正式运行该进程,进入运行状态;
3.当进程已经运行完成或出错时,会被操作系统作结束状态处理;
4.处于运行状态的进程在运行过程中,由于分配给它的运行时间片用完,操作系统会把该进程变为就绪态,接着从就绪态选中另外一个进程运行;
5.当进程请求某个事件且必须等待时,例如请求 I/O 事件的时候就会从运行状态变为阻塞状态;
6.当进程等待的事件完成的时候,就会从阻塞状态变成就绪态
同步 | 异步 & 阻塞 | 非阻塞
同步和异步描述的是任务的提交方式。
同步:任务提交之后,原地等待任务的返回结果,等待过程中不做任何事情,就是干等,程序层面上表现出来的就是卡住了,比如你去吃饭点了菜之后,就站在那等老板把菜给你端来....
异步:任务提交之后,不原地等待任务的返回结果,直接去做其他事情。比如去吃饭点了菜,老板给了你号码牌,等做好了,老板会喊你,不必站在那等菜做好。
阻塞和非阻塞描述的是程序的运行状态。阻塞和非阻塞这两个概念与程序等待消息通知(无所谓同步或者异步)时的状态有关。也就是说阻塞与非阻塞主要是程序(线程)等待消息通知时的状态角度来说的。
还拿上述点菜的例子来说,在等待菜做好的过程中,有的人就是干巴巴的等,什么也不做,这种机制就是阻塞态,表现在程序中就是程序一直阻塞在函数调用的地方无法继续执行;另外有些人在等上菜时会边打游戏边等,这样的状态就是非阻塞态。
同步阻塞形式的程序是效率最低的,拿上面的例子来说,就是你专心排队,什么别的事都不做。
异步阻塞状态,拿上面的例子来说就是拿着号码牌什么都不做。
同步非阻塞,实际效率也不高,以上面例子的来说就是站在那等菜顺便玩个游戏。
异步非阻塞是效率最高的,打游戏是你的事情,通知你拿菜的是老板的事情,再比如说这个人突然发觉自己烟瘾犯了,需要出去抽根烟,于是他告诉服务员说,排到我这个号码的时候麻烦到外面通知我一下,那么他就没有被阻塞在这个等待的操作上面,自然这个就是异步+非阻塞的方式了。
很多人会把同步和阻塞混淆,是因为很多时候同步操作会以阻塞的形式表现出来
,同样的,很多人也会把异步和非阻塞混淆,因为异步操作一般都不会在真正的IO操作处被阻塞
。