Chapter 8: Exceptional Control Flow

时间:2024-08-22 14:38:14

概述:

  我们可以用一种“流”的概念来理解处理器的工作流程,PC(Program Counter)依次为a0,a1,a2,...,an-1,这个序列可以称作control flow。当然我们并不总是按顺序执行,有时会遇到各种各样的异常使得an-1的下一个并不是an,最常见的就是交互设备的I/O。

  这一章我们就研究下exception control flow在计算机中扮演的重要角色!

Exception:

  Exception可以分为4种:Interrupt, Trap, Fault, Abort,主要区别如下:

Chapter 8: Exceptional Control Flow

  操作系统在启动过程中会分配一个exception table,如图。每个exception有其对应数字,这些对应一般是约定俗成的,比如exception 128(0x80)为system call。当exception发生时,系统就会根据这个表寻常相应处理方法,即exception handler。所以咱们遇到异常时的步骤可以归纳为:exception -> handler -> return。

Chapter 8: Exceptional Control FlowChapter 8: Exceptional Control Flow

Process:

  Process就是program加载入内存运行。我们同时运行多个进程其实只是一种错觉,单核处理器一次是只能运行一个进程的,但由于它的速度是在太快,所以我们感觉是多个进程在同时运行。这种情况我们称为concurrent,而parallel是指多核同时运行多个进程。

  每个process有自己的private address space,这样不同的process之间不至于互相干扰。

Chapter 8: Exceptional Control Flow

  每个process都有一个context记录其信息,这个context由系统内核维护,不同进程间的切换运行称作context switch。

Process Control:

  一个process有三种状态:Running, Stopped或Terminated。在linux中用pid(process id)来标示每个process,新建一个process通过fork()函数,从父进程中新建一个子进程,两个进程运行同一个程序,fork()返回两次,将子进程的pid返回给父进程,将0返回给子进程。利用这个特性我们可以如下编程:

#include "csapp.h"    /*本书配套的一个头文件*/

int main()
{
pid_t pid;
int x = ; pid = Fork();
if ( pid == ) { /*Child*/
printf("child : x=%d\n", ++x);
exit();
} /*Parent*/
printf("parent: x=%d\n", --x);
exit();
}

  通过if (pid == 0)这个判断来区别父进程与子进程所要执行的代码段。

  另一个常见的函数是execve(),用于在当前进程中加载另一个程序。

  而对于进程的结束有一点要注意,就是当子进程terminates之后,内核并不会马上将它从系统中移除,而是等待父进程将它收割。如果一个terminated的进程没有被reaped,就称作zombie!!! 好可怕啊~~

Signal:

  在高级的环境下,也就是软件方面的,我们用sinal来进行进程间的通信。并入说我们要关闭一个进程,就输入命令:(其中5000为所要关闭进程的pid)

# kill -     

  这个-9参数就是指号码为9的信号,即正常关闭signal。常见的还有15,强制关闭signal。

  signal有些特性,归纳起来就是

Signals can block and signals aren't queued。

随想:

  这一章有很多示例代码,可以多上机实践一下。