20135333苏正生——信息安全系统设计基础第十周学习总结

第八章 异常控制流

第一节 异常

1.产生:处理器中的变化(事件)触发从应用程序到异常处理程序的突发的控制转移,也就是异常;
2.类型:被零除,缺页,存储器访问违例,断点,算术溢出;系统调用,来着外部I/O设备的信号
3.处理:在任何情况下,当处理器检测到有事件发生时,它就会通过一张叫做异常表的跳转表进行一个间接过程调用,到一个专门处理这类时间的操作系统子程序(异常处理程序);
4.结果:当 exception handler处理结束之后,会有三种结果:
处理程序将控制返回给事件发生的时候正在执行的指令;
处理程序将控制返回给如果没有发生异常将会执行的下一条指令;
处理程序终止被终端的程序
(1)中断
(2)陷阱
(3)故障
(4)终止
5.Linux/IA32系统中的异常一共有256种
(1)Linux/IA32故障和终止
(2)Linux/IA32系统调用
系统调用的实现方法:
在IA32中,系统调用通过一条陷阱指令提供:
所有的到Linux系统调用的参数都是通过寄存器传递的。惯例如下:
%eax:包含系统调用号
%ebx,%ecx,%edx,%esi,%edi,%ebp:包含最多六个任意参数
%esp:栈指针,不能用

第二节 进程

进程定义:一个执行中的程序的实例。
系统中的每个程序都是运行在某个进程的上下文中的。
※上下文:由程序正确运行所需的状态组成的。
进程提供给应用程序的关键抽象:
一个独立的逻辑控制流:独占的使用处理器
一个私有的地址空间:独占的使用存储器系统
1.逻辑控制流
(1)进程计数器(PC)中的每一个值都唯一地对应于包含在程序的可执行目标文件中的指令,或者是包含在运行时动态链接的到程序的共享对象中的指令。这个PC值的序列叫做逻辑控制流。
(2)进程是轮流使用处理器的;每个进程执行它的流的一部分然后被挂起,其他进程执行。
(3)对于一个运行在其中一个进程上下文中的程序而言,它看上去就像是唯一地占用了处理器
2.并发流
(1)含义
一个逻辑流的执行在时间上与另一个流重叠。
这两个流并发的运行。
(2)几个概念:并发、多任务、时间片
(3)并行
两个流并发的运行在不同的处理机核或者计算机上。
并行流并行的运行,并行的执行。
3.私有地址空间
进程为程序提供的假象,好像它独占的使用系统地址空间。一般而言,和这个空间中某个地址相关联的那个存储器字节是不能被其他进程读写的。
4.用户模式和内核模式
区别:有无模式位,有的话就是内核模式,可以执行指令集中的所有指令,访问系统中任何存储器位置;没有就是用户模式。
5.上下文切换
操作系统内核使用上下文切换这种较高层形式的异常控制流来实现多任务。上下文切换机制建立在较底层异常机制之上。
(1)上下文:内核重新启动一个被抢占的进程所需的状态。
由一些对象的值组成:、通用目的寄存器、浮点寄存器、程序计数器、用户栈、状态寄存器、内核栈
内核数据结构:页表、进程表、文件表
(2)调度和调度器
(3)上下文切换机制
(4)可能发生上下文切换的原因:

第三节 系统调用错误处理

所有到linux的系统调用的参数都是通过通用寄存器而非栈来传递。按照惯例,寄存器%eax包含系统调用号,寄存器%ebx,%ecx,%edx,%esi和%ebp包含最多六个参数。%esp不适用,因为当进入内核模式的时候,内核会覆盖它。
举例说明 【以hello程序为例】

int main()
{
write(1,"hello world
",13);//用系统调用来写write函数
exir(0);
}

第四节 进程控制

一、获取进程ID

每个进程都有一个唯一的正数进程ID(PID)。

#include <sys/types.h>
#include <unistd.h>

pid_t getpid(void);	返回调用进程的PID
pid_t getppid(void);	返回父进程的PID(创建调用进程的进程)

二、创建和终止进程

1.进程三种状态:运行、停止、终止
2.创建进程
父进程通过调用fork函数来创建一个新的运行子进程。fork函数定义如下:

#include <sys/types.h>
#include <unistd.h>

pid_t fork(void);

fork函数只被调用一次,但是会返回两次:父进程返回子进程的PID,子进程返回0.如果失败返回-1.

在图8-15的代码为:

/* $begin fork */
#include "csapp.h"

int main() 
{
 pid_t pid;
 int x = 1;

 pid = Fork(); //line:ecf:forkreturn
 if (pid == 0) {  /* Child */
printf("child : x=%d
", ++x); //line:ecf:childprint
exit(0);
}

/* Parent */
printf("parent: x=%d
", --x); //line:ecf:parentprint
exit(0);
}
/* $end fork */

3.终止进程
用exit函数。

#include <stdlib.h>

void exit(int status);
exit函数以status退出状态来终止进程。

三、回收子进程

含义:当一个进程由于某种原因终止的时候,内核并不是把它从系统中清除,而是保持在已经终止的状态中,直到被它的父进程回收。这时,内核将子进程的退出状态传递给父进程,然后抛弃已经终止的进程。这之后,该进程才可以说是“不存在”了。
补充:已经终止但是尚未被回收的进程叫做僵死进程。
特例:如果父进程没有回收它的子进程就终止了,那么内核就会安排init函数来回收它们,init函数的返回值是1。waitpid函数的定义如下:

#include <sys/types.h>
#include <sys/wait.h>

pid_t waitpid(pid_t pid, int *status, int options);
成功返回子进程PID,如果WNOHANG,返回0,其他错误返回-1.

1.判断等待集合的成员——pid
2.修改默认行为——options
3.检查已回收子进程的退出状态——status
4.错误条件
5.wait函数
wait函数是waitpid函数的简单版本,wait(&status)等价于waitpid(-1,&status,0).

#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);

成功返回子进程pid,出错返回-1

四、让进程休眠

1.sleep函数
sleep函数使一个进程挂起一段指定的时间。
2.pause函数
让调用函数休眠,直到该进程收到一个信号。

问题:

本周问题有些多,而且很繁复,第八章难度确实有些大,之后整理一个博客专门写问题吧,然后把问题发到小组里去

心得体会

本周课程内容相对较多,有一些内容曾经接触过,有些在操作系统课上正在学,而有些则从未见过。再加上教学视频,感觉这些内容一周并不足够,可能还需要一点时间继续学习。再接再厉吧。

原文地址:https://www.cnblogs.com/suzhengsheng/p/4987800.html