本来以为自己的对于操作系统的基本理解应该是没有什么欠缺的,但是去搜刮了一波资料后发现自己好像啥都不会,本篇将主要总结:进程状态,CPU调度单位,中断实现机制,软硬中断的区别。
一 进程状态
通常而言,进程的状态分为两大类,一种是三模态,一种是五模态,它们的简介分别如下:
一个进程从创建而产生至撤销而消亡的整个生命期间,有时占有处理器执行,有时虽可运行但分不到处理器、有时虽有空闲处理器但因等待某个事件的发生而无法执行,这一切都说明进程和程序不相同,它是活动的且有状态变化的,这可以用一组状态加以刻画。为了便于管理进程,一般来说,按进程在执行过程中的不同情况至少要定义三种不同的进程状态:
- 运行(running)态:进程占有处理器正在运行。
- 就绪(ready)态:进程具备运行条件,等待系统分配处理器以便运行。
- 等待(wait)态:又称为阻塞(blocked)态或睡眠(sleep)态,指进程不具备运行条件,正在等待某个事件的完成。
通常,一个进程在创建后将处于就绪状态。每个进程在执行过程中,任意时刻当且仅当处于上述三种状态之一。同时,在一个进程执行过程中,它的状态将会发生改变。引起进程状态转换的具体原因如下:
- 运行态一一等待态:等待使用资源或某事件发生,如等待外设传输;等待人工干预。
- 等待态一一就绪态:资源得到满足或某事件己经发生,如外设传输结束;人工干预完成。
- 运行态一一就绪态:运行时间片到,或出现有更高优先权进程。
- 就绪态一一运行态:CPU空闲时被调度选中一个就绪进程执行。
在实际的工作中,进程的状态转化通常比三模态更加复杂一些,所以这里就引入了一个五模态的概念。
在一个实际的系统里进程的状态及其转换比上节叙述的复杂一些,例如,引入专门的新建态(new)和终止态(exit )。
引入新建态和终止态对于进程管理来说是非常有用的。新建态对应于进程刚刚被创建的状态,创建‘个进程要通过两个步骤,首先,是为一个新进程创建必要的管理信息;然后,让该进程进入就绪态。此时进程将处于新建态,它并没有被提交执行,而是在等待操作系统完成创建进程的必要操作。必须指出的是,操作系统有时将根据系统性能或主存容量的限制推迟新建态进程的提交。
类似地,进程的终止也要通过两个步骤,首先,是等待操作系统进行善后;然后,退出主存。当一个进程到达了自然结束点,或是出现了无法克服的错误,或是被操作系统所终结,或是被其他有终止权的进程所终结,它将进入终止态。进入终止态的进程以后不再执行,但依然保留在操作系统中等待善后。一旦其他进程完成了对终止态进程的信息抽取之后,操作系统将删除该进程。引起进程状态转换的具体原因如下:
- NULL一一新建态:执行一个程序,创建一个子进程。
- 新建态一一就绪态:当操作系统完成了进程创建的必要操作,并且当前系统的性能和内存的容量均允许。
- 运行态一一终止态:当‘个进程到达了自然结束点,或是出现了无法克服的错误,或是被操作系统所终结,或是被其他有终止权的进程所终结。
- 终止态一一NULL:完成善后操作。
- 就绪态一一终止态:未在状态转换图中显示,但某些操作系统允许父进程终结子进程。
- 等待态一一终止态:未在状态转换图中显示,但某些操作系统允许父进程终结子进程。
但是在linux系统中,进程的五种状态与上述的五模态还有一定的差别。linux系统中进程主要包含下面的五种状态:
- Linux进程状态:R (TASK_RUNNING),可执行状态&运行状态(在run_queue队列里的状态)
- Linux进程状态:S (TASK_INTERRUPTIBLE),可中断的睡眠状态, 可处理signal
- Linux进程状态:D (TASK_UNINTERRUPTIBLE),不可中断的睡眠状态, 可处理signal,有延迟
- Linux进程状态:T (TASK_STOPPED or TASK_TRACED),暂停状态或跟踪状态, 不可处理signal, 因为根本没有时间片运行代码
- Linux进程状态:Z (TASK_DEAD - EXIT_ZOMBIE),退出状态,进程成为僵尸进程。不可被kill, 即不响应任务信号, 无法用SIGKILL杀死
上述linux的五种状态在linux编程中有着非常重要的作用,这里很难三言两语将每个状态的作用详细介绍,日有有机会该部分将作为专题介绍。
二 CPU调度的最小单位
我们知道,在操作系统中,进程是操作系统分配的最小单位,对于cpu调度的最小单位不同地方有不同的答案。许多人认为线程是执行流的最小单位,但是对于cpu调度来说,每次执行并不一定完成一个线程的全部任务。我们可以发现所有的cpu调度算法都是为进程分配时间片,所以这里可以认为,时间片是cpu调度的基本单位。
三 软中断、硬中断&&实现机制
cpu和外部设备的速度总是不统一的,软件想要获取外部设备的状态主要有两种办法,一种是cpu不断地对所有的设备进行扫描,这样一旦设备发出信号,cpu就可以把时间告诉对应的应用程序。但是如果cpu同时连接了非常大量的外部设备,当一个设备发出信号时,cpu却在轮询其他设备,这中间的时间差会产生大量的延迟。而且cpu不断地访问空闲设备一定程序上也会浪费cpu的资源。
所以在这里,操作系统会选择中断机制来解决这个问题。当没有中断产生的时候,cpu正常执行程序,当中断产生的时候,cpu会暂停当前进行的操作来处理中断,当中断处理完成后又将恢复执行正常程序。操作系统响应中断的基本流程如下。
产生中断——响应中断——关闭中断——保护中断——识别中断源——现场保护——中断服务——现场恢复。
中断又常被分为软中断和硬中断对于他们的特点引用csdn博客内容:
硬中断:
- 硬中断是由硬件产生的,比如,像磁盘,网卡,键盘,时钟等。每个设备或设备集都有它自己的IRQ(中断请求)。基于IRQ,CPU可以将相应的请求分发到对应的硬件驱动上(注:硬件驱动通常是内核中的一个子程序,而不是一个独立的进程)。
- 处理中断的驱动是需要运行在CPU上的,因此,当中断产生的时候,CPU会中断当前正在运行的任务,来处理中断。在有多核心的系统上,一个中断通常只能中断一颗CPU(也有一种特殊的情况,就是在大型主机上是有硬件通道的,它可以在没有主CPU的支持下,可以同时处理多个中断。)。
- 硬中断可以直接中断CPU。它会引起内核中相关的代码被触发。对于那些需要花费一些时间去处理的进程,中断代码本身也可以被其他的硬中断中断。
- 对于时钟中断,内核调度代码会将当前正在运行的进程挂起,从而让其他的进程来运行。它的存在是为了让调度代码(或称为调度器)可以调度多任务。
软中断:
- 软中断的处理非常像硬中断。然而,它们仅仅是由当前正在运行的进程所产生的。
- 通常,软中断是一些对I/O的请求。这些请求会调用内核中可以调度I/O发生的程序。对于某些设备,I/O请求需要被立即处理,而磁盘I/O请求通常可以排队并且可以稍后处理。根据I/O模型的不同,进程或许会被挂起直到I/O完成,此时内核调度器就会选择另一个进程去运行。I/O可以在进程之间产生并且调度过程通常和磁盘I/O的方式是相同。
- 软中断仅与内核相联系。而内核主要负责对需要运行的任何其他的进程进行调度。一些内核允许设备驱动的一些部分存在于用户空间,并且当需要的时候内核也会调度这个进程去运行。
- 软中断并不会直接中断CPU。也只有当前正在运行的代码(或进程)才会产生软中断。这种中断是一种需要内核为正在运行的进程去做一些事情(通常为I/O)的请求。有一个特殊的软中断是Yield调用,它的作用是请求内核调度器去查看是否有一些其他的进程可以运行。
这里引用百度百科介绍中断的概念。
虽然人们在谈到中断(Interrupt)时,总会拿轮询(Polling)来做“反面”例子,但中断和轮询并不是完全对立的两个概念,呃,它们是对立统一的。
“CPU执行完每条指令时,都会去检查一个中断标志位”,这句话是所有关于中断长篇大论的开场白,但很容易被人忽略,其实,这就是中断的本质。
举个例子,CPU老板是一家公司的光杆司令,所有的顾客都要他亲自跑去处理,还要跟有关部门打点关系,CPU觉得顾客和公关这两样事它一个人搞不来,这就是轮询;终于这家公司升级发展了,CPU老板请了一个秘书,所有的顾客都先由秘书经手,CPU心情好的时候就去看一下,大部分时间都忙着去公关了,这时它觉得轻松了很多,这就是中断了~~
也就是说,中断和轮询是从CPU老板的角度来看的,不管怎样,事件都还是有人来时刻跟踪才能被捕获处理,不过是老板还是秘书的问题。所有的中断(或者异步,回调等)背后都有一个轮询(循环,listener)。