1:诸如子进程结束之后父进程需要被告知,有时候应用程序需要系统调用,内核通过上下文切换将控制从一个进程切换到另一个进程,还有一个进程发送信号到另一个进程时接收者转而到它的信号处理函数去执行等等,我们的操作系统,甚至硬件无时无刻不在发生“突变”,我们把这种突变叫做异常控制流。即ECF(Exceptional Control Flow),它发生在计算机系统的各个层次。

2:为什么要理解异常控制流:

(1):ECF是操作系统实现I/O,虚拟存储,进程的基本机制。

(2):这将有助于你理解应用程序是怎样和操作系统交互的,实际上是通过“陷阱”或者叫“系统调用”的方式。比如写磁盘,从网络中读取数据,创建一个进程,等等

(3):操作系统为应用程序提供了强大的系统调用去使用,创建进程,通知其他进程系统,发送信号给其他进程等等,理解这些之后我们就不难写出有趣的程序了,例如一些web程序。

(4):理解ECF将使你真正的理解并发,还可以帮你理解软件是如何工作的,例如向setjmp和longjmp为什么可以实现跳转等等,也将会和你学到的C++的try函数以及catch函数加深理解。

3:异常

为什么要说异常,因为正常的很少,这个世界本来就是不正常的情况多,哪有那么多风平浪静的时候,扯得有点远。我们继续,异常的实现有硬件,有软件,假设现在有一个进程A正在运行,它突然需要调用read()函数从磁盘读取文件,此时由于read()函数属于系统调用,即要进入内核才可以使用的,所以当前的代码以及下面的代码就应该被保存下来,当然这是要进入内核态,我们就把遇到这个read()函数叫做“事件”,即它是一种状态的变化,我们的操作系统有一张叫做“异常表”的跳转表的东西,跳转到遇到这类信号应该去执行的代码的地方。

C++和java程序员会注意到术语“异常”也用来描述由C++和java以及catch,throw,和try语句形式提供的应用程序层的ECF,如果必须弄清楚,这就要牵扯到硬件和软件的不同了。

下面具体来描述下我们操作系统对于异常的处理:

在我们的系统中,每一个异常都对应一个特定的异常号,其中一些是硬件的设计者分配的,其他号码是由操作系统内核分配的,前者包括除0错,硬件设备异常,虚拟存储器缺页异常,存储器访问异常,等等,后者包括我们的系统调用和来自外部的I/O设备的信号。当操作系统启动的时候,内核会专门为我们分配并且初始化一张称为异常表的跳转表,其中按照不同的异常编号存放的是对应的处理异常的代码的地址。异常号是在异常表中的索引,异常表的起始地址存放在一个叫做异常表基址寄存器的特殊cpu寄存器里。

4:异常的种类:

一共有4种异常的种类:中断,陷阱和系统调用,故障,终止

中断:据说是异步的,但是这个异步怎么理解,苗帅学长这样解释:因为中断一般指的就是硬件中断,硬件发生中段的情况是随机的,是不为我们所知道的,所以这种情况我们称之为异步,这也就是中断,但是对于别的三种情况,诸如系统调用这是一种有意的异常,是执行一条指令的结果,并且我们知道它发生在了哪个地方。

陷阱和系统调用:可以说是一种有意的异常,只是我们异常处理的时候,会有内核为我们提供的通道去获得更大的权利,并且我们可以访问内核中的栈,它返回到我们的下一条指令。

故障:故障是由错误情况引起的,它可能能够被故障处理程序修正,如果能修正,返回到引起故障的指令,要是修复不了,那就返回到内核中的abort例程结束应用程序。

终止:终止是不可恢复的致命错误造成的结果,通常是一些硬件错误。直接到abort例程。

5:理解下并发的概念:

条件:如果流x和流y并发,那么满足情况有两种:

1:x在y开始之后并且y结束之前开始

2:y在x开始之后并且x结束之前开始

所以说并发是可以在单核CPU上跑的,不一定要多核,我觉得这以前是个误区。

6:用户模式和内核模式:

由于进程为我们每个程序提供了一种假象,即我们的每个程序都独占内存空间,并且看起来在某一时刻只有我们这一个程序在运行,为了将这种假象提供的完美,我们的处理器必需提供一种机制,限制一个应用可以执行的指令和它可以访问的存储器的位置,处理器通常是用某个控制寄存器的中的一个模式位来提供这种功能,没有设置模式位时,进程就运行在用户模式中,但是设置了模式位之后,我们的应用程序就获得了特权,进程就运行在了内核模式中,一个运行在内核模式中的进程可以执行指令集中的所有指令,访问所有存储位置。

linux为我们提供了一种聪明的机制:叫做“/proc”文件系统,它允许用户模式进程访问“内核数据结构的位置”,注意:访问的是位置,而不是内容。/proc文件系统将许多数据结构的内容输出为一个用户程序可以读的文本文件的层次结构。如:/proc/cupinfo

7:内核会为每一个进程维护一个上下文,上下文说的简单些就是进程目前的状态信息,我们通过保存这个上下文来达到我们能回到某个进程的某个运行状态,前提是发生过上下文切换之后。在进程执行的某个瞬间,内核有权利决定“抢占”当前的进程,并且通过上下文切换切换到另一个进程,这样可以减少资源的浪费(举一个例子:当某个应用调用read读取磁盘的时候,由于磁盘的读取速度是比较慢的,这时候内核可不会一直等几十毫秒,他自己会做决定切换上下文,可是凭什么切换呢?凭“时间片”,比如所有的系统都有某种产生周期性定时器中断的机制通常为1毫秒或者10毫秒),等到read()函数返回的时候,再将控制程序返回给调用read()函数的进程。

版权声明:本文为博主原创文章,未经博主允许不得转载。

CSAPP学习笔记(异常控制流1)的更多相关文章

  1. CSAPP学习笔记—虚拟内存

    CSAPP学习笔记—虚拟内存 符号说明 虚拟内存地址寻址 图9-12展示了MMU如何利用页表来实现这种映射.CPU中的一个控制寄存器,页表基址寄存器(Page Table Base Register, ...

  2. 《深入理解计算机系统》学习笔记整理(CSAPP 学习笔记)

    简介 本笔记目前已包含 CSAPP 中除第四章(处理器部分)外的其他各章节,但部分章节的笔记尚未整理完全.未整理完成的部分包括:ch3.ch11.ch12 的后面几小节:ch5 的大部分. 我在整理笔 ...

  3. python学习笔记——异常

    转自 http://www.cnblogs.com/rubylouvre/archive/2011/06/22/2086644.html Python内建异常体系结构 BaseException +- ...

  4. 0016 Java学习笔记-异常-如果try-catch-finally中都存在return语句会怎样?

    上午在搜索"System.runFinalization"的时候,搜到 http://www.cnblogs.com/Skyar/p/5962253.html ,其中有关于try- ...

  5. Python学习笔记异常

    在程序代码中,可能会有各种错误的情况出现,且产生错误的结果是后面的代码都无法执行,即使是一点无关紧要的错误,如图: 在这样的情况下,我们需要异常处理,对程序代码中的错误抛出异常信息,且不影响后面的代码 ...

  6. java学习笔记 --- 异常

    异常 (1)程序出现的不正常的情况. (2)异常的体系   Throwable    |--Error  错误,严重问题,我们不处理.    ·    |--Exception 异常     |--R ...

  7. Java学习笔记--异常描述

    异常描述 1.简介 为了全面了解"异常"的概念,先来分析一个实例.假定要编写一个Java程序,该程序读取用户输入的一行文本,并在终端显示该文本.这里是一个演示Java语言I/O功能 ...

  8. kotlin学习笔记-异常好玩的list集合总结

    不积跬步无以至千里,不积小流无以成江海 先看看Kotlin中for循环的遍历 fun testList(){ var StringVal = "12_12_13_15_a_b_c_d_yu_ ...

  9. 《Effective Java》学习笔记 ——异常

    充分发挥异常的优点,可以提高程序的可读性.可靠性和可维护性. 第57条 只针对异常的情况才使用异常 第58条 对可恢复的情况使用受检异常,对编程错误使用运行时异常 * 如果期望调用者能够适当的恢复,使 ...

随机推荐

  1. LeetCode----Tree

    Path Sum II 思路:回溯 public List<List<Integer>> pathSum(TreeNode root, int sum) { List<L ...

  2. 转载:scala中:: , +:, :+, :::, ++的区别

    原文链接:https://segmentfault.com/a/1190000005083578 初学Scala的人都会被Seq的各种操作符所confuse.下面简单列举一下各个Seq操作符的区别. ...

  3. linux 持续构建(自动部署) 重启动tomcat或进程的脚本

    #!/bin/sh TOMCAT_PATH=`dirname "$0"` echo "TOMCAT_PATH is /usr/local/tomcat" PID ...

  4. 【转】libevent和基于libevent的网络编程

    转自: http://www.cnblogs.com/nearmeng/p/4043548.html 1 libevent介绍和安装 介绍 libevent是一个轻量级的基于事件驱动的高性能的开源网络 ...

  5. TObject、Pointer、Interface的转换

    unit Unit4; ));   ));   ));   //将Obj转为接口   //LInf1 := ITest(Pointer(LObj1));       //无法转换了,丢失了接口信息   ...

  6. HTML5精美网站模板分享

    1. http://newweb.top/ 2. http://newweb.top/Templates/agency-gh-pages/index.html

  7. 小例子 熟悉jquery

    <div class="tab-head"> <h2 id="tab1" class="selected">JQGr ...

  8. c# 进程间的通信实现之一简单字符串收发

       使用Windows API实现两个进程间(含窗体)的通信在Windows下的两个进程之间通信通常有多种实现方式,在.NET中,有如命名管道.消息队列.共享内存等实现方式,这篇文章要讲的是使用Wi ...

  9. Android基础之Activity四种启动模式

    这东西是最基础的,发现自己其实没有真正试过,好好研究研究 standard :默认, singleTop :大体上同standard,但是当该Activity实例已经在task栈顶,不再创建新的实例, ...

  10. 详解c++指针的指针和指针的引用(转)

    http://www.cnblogs.com/li-peng/p/4116349.html