目录
并发就是多个进程在一个cpu上,在一段时间内,多个进程都可以进行推进,称之为并发。
并行就是多个进程在多个cpu下,同时进行运行,这称之为并行。
其实上面的五型模型其实是有争议的,因为官方上讲就绪也称为运行,实际上要讲的主要内容其实是围绕运行和阻塞的。
了解了进程的状态这种哲学层面的,再来了解一下linux上具体的进程的状态:
1.进程的状态
在众多linux教材中都有如上图所解释的哲学层面的,可以应用于任何操作系统上的进程的状态模型。
只不过在用户层面上感受不到,因为cpu切换和运行的速度非常快。
接下来解释一下并行和并发:
并发就是多个进程在一个cpu上,在一段时间内,多个进程都可以进行推进,称之为并发。
cpu执行进程代码,不是把进程代码执行完毕,才开始执行下一个。
而是给每个进程预分配一个时间片,基于时间片,进行调度轮转(单CPU下),并发。
白话就是多个进程先按照调度器来进行调度,每个进程进入到运行状态只执行一部分,在经过进程的五态模型,轮转进行调度,最后完成所有进程的任务。
并行就是多个进程在多个cpu下,同时进行运行,这称之为并行。
区别在于:单CPU和多CPU,时间段和同时进行。
接下来解释一下时间片:
linux/windows民用级别的操作系统都是分时操作系统,就是给每个进程分配一定的时间片进行轮转执行,当然调度任务是追求公平的每个进程的时间片会有所不同。
实时操作系统:企业级可以使用的到。
进程具有独立性:
父进程和子进程都具有独立性,子进程挂掉了,不影响父进程。
其实上面的五型模型其实是有争议的,因为官方上讲就绪也称为运行,实际上要讲的主要内容其实是围绕运行和阻塞的。
等待的本质:
空出cpu,进入目标外部设备。
在内核级数据结构方面上讲,进程的status(所谓的状态),其实是用的#define RUNNING 1/#define BLOCK 2类似这种来表示的,也就是进程的pcb进程控制块里的属性status是int类型的。
接下来解释一下为什么争议的问题:
首先先明确有cpu、内存和操作系统三个结构,遵循着冯诺依曼体系结构,进程是从硬盘上调入内存在经过cpu再给到外设。
“先描述,再组织”
进程包括代码、数据和PCB进程控制块
通过链表的数据结构来构成对链表的增删查改。
这里需要一个struct runqueue运行队列:包括属性+task_struct* head,来链接所有的在运行态的PCB。
这里要明确知道只要进程在运行队列中,该进程就叫做运行状态。即我已经准备好了,可以被CPU随时调度了。
接下来认识一下操作系统是如何管理底层硬件的呢?
这里依旧是"先描述,再组织"
定义一个struct结构体对象device,里面包含属性+next结构体指针。
通过struct device* devices结构体指针来链接所有的结构体对象,最后就变成了最链表的增删查改。
有了知识铺垫,这时就可以学一下阻塞状态了:
通过最上面的图可知I/O请求时会进入阻塞状态,阻塞状态就是从cpu换出,调入到硬件管理,也就是外设的问题了。
其实device结构体对象里面还有一个变量叫wait_queue即等待队列,从运行态到阻塞态就是将代码和数据+pcb进程控制块从运行队列拿到设备PCB的等待队列中。
所以运行和阻塞的本质:是让不同的进程,处在不同的队列中!
比如说:scanf函数在键盘设备pcb控制块中,此时阻塞,一旦键盘输入数据,进程就从等待队列进入到运行队列
接下来了解一下挂起:
首先了解背景:是在内存资源严重不足的时候,进程会进入到挂起状态。
比如日常当中我们用的安卓操作系统,开了很多的软件,我们知道操作系统是管理软硬件资源的一款软件,在开机时操作系统是先调入到内存中的,再怎么样软件挂掉也不能让操作系统挂掉,一旦内存资源严重不足时,操作系统就意识到危机了就会采取措施。
磁盘当中有一块空间叫做swap分区,操作系统就会将一些进程当中的运行过的数据换出到swap里,为了腾出内存空间,将进程从等待队列调入到运行队列中去,直到到这个进程时,先从运行队列到等待队列,再从磁盘中的swap分区换入到进程当中。
这个过程是在I/O设备上操作的,也就是所谓的“慢”,这种方法叫做:“用时间换空间”。
这种过程叫做"挂起",也就是阻塞挂起状态。
当然也是了解一下,实际上在互联网公司这种挂起状态是不被允许的,因为会大大的影响公司的运作,慢也就是其原因,解决方法也就是搞多台服务器。
了解了进程的状态这种哲学层面的,再来了解一下linux上具体的进程的状态:
static const char *const task_state_array[] = {
"R (running)", /*0 */
"S (sleeping)", /*1 */
"D (disk sleep)", /*2 */
"T (stopped)", /*4 */
"t (tracing stop)", /*8 */
"X (dead)", /*16 */
"Z (zombie)", /*32 */
};
R运⾏状态(running):
S休眠状态(sleeping):
D磁盘休眠状态(Disk sleep):
比如说:存在进程A、操作系统和磁盘,今天模拟一个银行存储的故事,内存中现在已经有了进程A,进程A给磁盘说:磁盘我有100w个银行交易数据你能帮我存一下吗?磁盘回复:可以啊,你拿过来吧。此时磁盘就开始帮忙存数据了,可是磁盘由于容量不足存不下了,想告诉进程A时,进程A被强制杀掉了,此时磁盘按照以往的习惯就取消掉已经存储的一些数据了,可是这就造成了数据丢失了!那这三人就说不清了,互相指责,此时行长也蒙圈了,产生了自我怀疑,难道是我的问题?
此时行长就设定了一种状态D:叫做深度睡眠,不可被杀掉。所以disk(也就是磁盘)也是阻塞等待状态的一种。