Linux系统的中断、系统调用和调度概述【转】
转自:http://blog.csdn.net/yanlinwang/article/details/8169725
版权声明:本文为博主原创文章,未经博主允许不得转载。
最近学习Linux操作系统,关于中断系统调用和进程的级别总是感觉有些模糊的地方,特在此做个小结,整理下思路。
所谓的中断就是在计算机执行程序的过程中,由于出现了某些特殊事情,使得CPU暂停对程序的执行,转而去执行处理这一事件的程序。等这些特殊事情处理完之后再回去执行之前的程序。中断一般分为三类:1、由计算机硬件异常或故障引起的中断,称为内部异常中断;2、由程序中执行了引起中断的指令而造成的中断,称为软中断(这也是和我们将要说明的系统调用相关的中断);3、由外部设备请求引起的中断,称为外部中断。简单来说,对中断的理解就是对一些特殊事情的处理。
与中断紧密相连的一个概念就是中断处理程序了。当中断发生的时候,系统需要去对中断进行处理,对这些中断的处理是由操作系统内核中的特定函数进行的,这些处理中断的特定的函数就是我们所说的中断处理程序了。
另一个与中断紧密相连的概念就是中断的优先级。中断的优先级说明的是当一个中断正在被处理的时候,处理器能接受的中断的级别。中断的优先级也表明了中断需要被处理的紧急程度。每个中断都有一个对应的优先级,当处理器在处理某一中断的时候,只有比这个中断优先级高的中断可以被处理器接受并且被处理。优先级比这个当前正在被处理的中断优先级要低的中断将会被忽略。
典型的中断级如下所示
当发生软件中断时,其他所有的中断都可能发生并被处理;但当发生磁盘中断时,就只有时钟中断和机器错误中断能被处理了。
在讲系统调用之前,先说下进程的执行在系统上的两个级别:用户级和核心级,也称为用户态和系统态(user mode and kernel mode)。程序的执行一般是在用户态下执行的,但当程序需要使用操作系统提供的服务时,比如说打开某一设备、创建文件、读写文件等,就需要向操作系统发出调用服务的请求,这就是系统调用。Linux系统有专门的函数库来提供这些请求操作系统服务的入口,这个函数库中包含了操作系统说提供的对外服务的接口。当进程发出系统调用之后,它所处的运行状态就会由用户态变成核心态。但这个时候,进程本身其实并没有做什么事情,这个时候是由内核在做相应的操作,去完成进程所提出的这些请求。
系统调用和中断的关系就在于,当进程发出系统调用申请的时候,会产生一个软件中断。产生这个软件中断以后,系统会去对这个软中断进行处理,这个时候进程就处于核心态了。
那么用户态和核心态之间的区别是什么呢?(以下区别摘至《UNIX操作系统设计》)
1、用户态的进程能存取它们自己的指令和数据,但不能存取内核指令和数据(或其他进程的指令和数据)。然而,核心态下的进程能够存取内核和用户地址
2、某些机器指令是特权指令,在用户态下执行特权指令会引起错误
对此要理解的一个是,在系统中内核并不是作为一个与用户进程平行的估计的进程的集合,内核是为用户进程运行的。
如何去理解上面所说的区别,特别是区别1呢?真正理解这点,需要对进程在内存中的表示有个大致的理解。
每个程序需要被装入(全部或部分)装入内存后才能开始运行,在32位机器中,每个进程都有4G的虚拟地址空间。但是对这4G的空间并不是全部都可以被进程使用的,在Linux中,对这4G的空间的大致划分如下
因此,从原则上来说,在进程中用户能使用的虚拟地址空间是只有3G的。正常情况下,用户程序在用户态运行的时候,只能访问在这3G范围内的地址(当然也不是所有地址都能访问)。当进程由于系统调用而进入核心态时,这时系统内核会执行相应的操作,它能访问自己1G的地址空间,同时也能访问3G的用户地址空间。而用户进程的指令的数据是存在与那3G的地址空间中的。当然还有进程的栈等部分。
细分来说的话,一个进程在内存中一般包含以下部分,数据段、指令段、运行时堆、栈等。示意图如下
内核自己的栈这在最上层的1G的地址空间内,这是只能由内核访问的部分。
在说进程调度之前,首先整理下进程可能的各种状态。首先我们知道进程的运行状态是分为核心态和用户态。其他的进程状态包括如下
进程未被执行,但出于就绪状态,只要内核调度它,即可执行
进程正在睡眠中并且存在主存中
进程处于就绪状态,但处在二级存储器中
进程在睡眠中,且在二级存储器中
进程执行完核心态的操作,正要返回用户态时,内核做了进程调度,切换了上下文
进程刚被创建
进程调用了exit,处于僵死状态
进程之间的状态转换示意图如下,箭头指明了转换的方向
进程的各种状态的转换比较复杂,这里主要关注进程的两个运行状态、睡眠以及从就绪到运行的转换
从示意图中可以看出,当发生中断或者系统调用时,进程由用户态转成核心态。但进程在核心态运行时,是不能被抢占的,因此只有当进程由核心态进入睡眠状态时,或者进程处于用户态时,内核才允许做进程调度,切换上下文。而处于就绪状态的进程当被内核调度开始运行的时候,首先是进入核心态的。
那么为什么,进程在核心态运行的时候,不允许做进程调度呢?因为在核心态运行的时候,需要访问一些全局核心数据结构中的信息。如果运行在核心态时的进程调度,那么会改变内核运行时的进程上下文,而这些不同的进程上下文对同一个核心数据可能会有不同的操作要求,这样将有可能会破坏全局核心数据结构中的信息。为了保证内核核心数据的一致性,当进程处于核心态时,是不允许进行上下文切换的。
这就涉及到另一个问题,中断是在任何时刻都能发生的,并且对中断的处理也可能影响内核数据的一致性。那么,但进程在核心态运行时,对于发生中断的情况又如何保证内核数据的一致性呢?解决的方法大致分为两类,一种是简单地在核心态时,禁止所有的中断,但这样会降低对中断的响应速度;另一种方法是设立临界区,找出操作语句中可能会导致内核数据不一致的地方,然后将这部分设为临界区。但CPU执行临界区代码时,把CPU的执行级别提高,这样就可以屏蔽掉很多的中断,从而保证数据的一致性了。一般,为了保证系统的性能,临界区都很小,并且不会经常出现。
Linux系统的中断、系统调用和调度概述【转】的更多相关文章
- Linux系统——常见的系统调用
本文列出了大部分常见的Linux系统调用,并附有简要中文说明. 以下是Linux系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的的函数.这可能是你在互联网上所能看到的唯一一篇中文注释的 ...
- linux系统中中断已连接的用户
1.用w命令查看当前系统登录的用户 [root@rhel7 ~]# w :: up :, users, load average: 0.00, 0.01, 0.05 USER TTY FROM LOG ...
- Linux 系统内存分析
1. 内存基本介绍 1.计算机基本结构: 电脑之父--冯·诺伊曼提出了计算机的五大部件:输入设备.输出设备.存储器.运算器和控制器 如图: 输入设备:键盘鼠标等 CPU:是计算机的运算核心和控制核心, ...
- linux系统编程之信号(七):被信号中断的系统调用和库函数处理方式
一些IO系统调用执行时, 如 read 等待输入期间, 如果收到一个信号,系统将中断read, 转而执行信号处理函数. 当信号处理返回后, 系统遇到了一个问题: 是重新开始这个系统调用, 还是 ...
- linux中断源码分析 - 概述(一)
本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 关于中断和异常 一般在书中都会把中断和异常一起说明,因为它们具有相同的特点,同时也有不同的地方.在CPU里,中断 ...
- Linux系统编程:基本I/O系统调用
文件描述符 进程每打开一个文件的时候,会获得该文件的文件描述符,而后续的读写操作都把文件描述符作为参数.在用户空间或者内核空间,都是通过文件描述符来唯一地索引一个打开的文件.文件描述符使用int类型表 ...
- 再思linux内核在中断路径内不能睡眠/调度的原因(2010)【转】
转自:http://blog.csdn.net/maray/article/details/5770889 Linux内核中断路径中不能睡眠,为什么? 这里就行了很深入的讨论,值得一看:http:// ...
- linux系统编程(一)概述
glibc库封装了linux系统调用,并提供c语言接口 所以学习linux系统编程,主要参考glibc库系统调用相关api 一.进程控制: fork 创建一个新进程 clone 按指定条件创建子进程 ...
- Linux系统编程(2)——文件与IO之系统调用与文件IO操作
系统调用是指操作系统提供给用户程序的一组"特殊"接口,用户程序可以通过这组"特殊"接口来获得得操作系统内核提供的特殊服务.在linux中用户程序不能直接访部内核 ...
随机推荐
- shell && 和 || 的短路使用
shell && 和 || 的短路使用 && 和 || 在 shell 中分别表示 and 和 or,和其它语言类似,这两个操作有短路效应.也就是说,当判断式已经确定时 ...
- LINQ使用
基于扩展方法和lamda表达式 1. 查询序列中满足一定条件 Where扩展方法 public interface ISlotPortBinding { byte SlotNumber { get; ...
- vs2015 使用 visual studio on line 在线版本控制
将visual studio on line 作为一个免费在线版本控制器还是不错的,可以支持5个免费用户共同开发, 以下作为记录,贴在此. 一 申请visual studio on line 账户. ...
- javascript设计模式学习之四——单例模式,缓存与对象池
单例模式的定义:确保一个实例,并提供全局访问. 惰性单例的定义:只在需要的时候才创建对象. 在开发中,有些对象往往只需要一个,比如线程池.全局缓存.浏览器中的window对象等. java中的单例 关 ...
- nginx 日志分析
Nginx中日志文件的格式在nginx.conf中定义,其默认格式如下: #vim /usr/local/nginx/conf/nginx.conf log_format acces ...
- Angular.js+Bootstrap实现表格分页
最近一直学习Angular.js,在学习过程中也练习了很多的Demo,这里先贴一下表格+分页. 先上图看看最终结果: 不得不说Angular.js代码风格很受人欢迎,几十行代码清晰简洁的实现了上面的功 ...
- 从零开始PHP攻略(2)——操作符与迭代整理
目录: 10.操作符整理 11.表单计算代码 12.优先级与结合性 13.可变函数 14.条件判断 15.循环迭代 16.跳出控制 17.可替换的控制结构 10.操作符 10.1 算术操作符 算术操作 ...
- spring AutowireCapableBeanFactory 自动注入
文档:http://docs.spring.io/spring/docs/3.0.x/javadoc-api/org/springframework/beans/factory/config/Auto ...
- 根据搜素的字符串改变label包含该字符串的文字
http://www.2cto.com/kf/201504/391811.html NSString *text =@"人生若只如初见"; //判断字符串所在的位置,并不区分大小写 ...
- [原创]java WEB学习笔记68:Struts2 学习之路-- 类型转换与复杂属性配合使用
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...