转自: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系统的中断、系统调用和调度概述【转】的更多相关文章

  1. Linux系统——常见的系统调用

    本文列出了大部分常见的Linux系统调用,并附有简要中文说明. 以下是Linux系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的的函数.这可能是你在互联网上所能看到的唯一一篇中文注释的 ...

  2. linux系统中中断已连接的用户

    1.用w命令查看当前系统登录的用户 [root@rhel7 ~]# w :: up :, users, load average: 0.00, 0.01, 0.05 USER TTY FROM LOG ...

  3. Linux 系统内存分析

    1. 内存基本介绍 1.计算机基本结构: 电脑之父--冯·诺伊曼提出了计算机的五大部件:输入设备.输出设备.存储器.运算器和控制器 如图: 输入设备:键盘鼠标等 CPU:是计算机的运算核心和控制核心, ...

  4. linux系统编程之信号(七):被信号中断的系统调用和库函数处理方式

        一些IO系统调用执行时, 如 read 等待输入期间, 如果收到一个信号,系统将中断read, 转而执行信号处理函数. 当信号处理返回后, 系统遇到了一个问题: 是重新开始这个系统调用, 还是 ...

  5. linux中断源码分析 - 概述(一)

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 关于中断和异常 一般在书中都会把中断和异常一起说明,因为它们具有相同的特点,同时也有不同的地方.在CPU里,中断 ...

  6. Linux系统编程:基本I/O系统调用

    文件描述符 进程每打开一个文件的时候,会获得该文件的文件描述符,而后续的读写操作都把文件描述符作为参数.在用户空间或者内核空间,都是通过文件描述符来唯一地索引一个打开的文件.文件描述符使用int类型表 ...

  7. 再思linux内核在中断路径内不能睡眠/调度的原因(2010)【转】

    转自:http://blog.csdn.net/maray/article/details/5770889 Linux内核中断路径中不能睡眠,为什么? 这里就行了很深入的讨论,值得一看:http:// ...

  8. linux系统编程(一)概述

    glibc库封装了linux系统调用,并提供c语言接口 所以学习linux系统编程,主要参考glibc库系统调用相关api 一.进程控制: fork 创建一个新进程 clone 按指定条件创建子进程 ...

  9. Linux系统编程(2)——文件与IO之系统调用与文件IO操作

    系统调用是指操作系统提供给用户程序的一组"特殊"接口,用户程序可以通过这组"特殊"接口来获得得操作系统内核提供的特殊服务.在linux中用户程序不能直接访部内核 ...

随机推荐

  1. cat 命令(转)

    cat命令的用途是连接文件或标准输入并打印.这个命令常用来显示文件内容,或者将几个文件连接起来显示,或者从标准输入读取内容并显示,它常与重定向符号配合使用. 1.命令格式: cat [选项] [文件] ...

  2. ucenter 4站同步

    其中fleam站的登陆代码为下,通过登陆fleam的账号,引发其他3个站点的登陆 <meta charset="utf8"> <?php include 'con ...

  3. C# 键盘钩子类

    键盘钩子类代码如下 class globalKeyboardHook { #region Constant, Structure and Delegate Definitions /// <su ...

  4. IntelliJ IDEA 自动导入包 快捷方式

    idea可以自动优化导入包,但是有多个同名的类调用不同的包,必须自己手动Alt+Enter设置 设置idea导入包 勾选标注 1 选项,IntelliJ IDEA 将在我们书写代码的时候自动帮我们优化 ...

  5. 第十四篇 Integration Services:项目转换

    本篇文章是Integration Services系列的第十四篇,详细内容请参考原文. 简介在前一篇,我们查看了SSIS变量,变量配置和表达式管理动态值.在这一篇,我们使用SQL Server数据商业 ...

  6. 第一篇 SQL Server代理概述

    本篇文章是SQL Server代理系列的第一篇,详细内容请参考原文. SQL Server代理是SQL Server的作业调度和告警服务,如果使用得当,它可以大大简化DBA的工作量.SQL Serve ...

  7. shapely and geos break在distance方法

    问题 from shapely.geometry import Point print Point(0,0).distance(Point(1,1)) 报错 python: GeometryCompo ...

  8. LUA 模块化编程例子

    LUA module lua语言中module接口用于定义一个模块, 将模块的实现封装到一个文件中, 开放的 函数 和 数据, 不以local标识,然后在其他文件中, 引用此模块, 使用模块名(一个命 ...

  9. 抽取AWR数据

    使用$ORACLE_HOME/rdbms/admin/awrextr.sql $ sqlplus '/as sysdba' SQL*Plus: Release Production on Fri No ...

  10. jQuery中的siblings

    所谓siblings,英文翻译就是兄弟节点.那么故名思意,就是拿到某元素的兄弟节点(不包括自己). <html> <head> <script type="te ...