# 2017-2018-1 20155337《信息安全系统设计基础》第十四周学习总结
2017-2018-1 20155337《信息安全系统设计基础》第十四周学习总结
我认为本书重要的一章也是我学的比较困难的的一章就是第八章
--异常控制流。
- 控制流:控制转移序列。
- 控制转移:从一条指令到下一条指令。
- 异常控制流:现代操作系统通过使控制流发生突变来对系统状态做出反应,这些突变称为异常控制流。
一、异常(硬件触发异常,软件处理异常)
1、异常的剖析,如下图所示:
2、异常处理
- 异常表:当处理器检测到有事件发生时,它会通过跳转表,进行一个间接过程调用(异常),到异常处理程序。
- 异常号:系统中可能的某种类型的异常都分配了一个唯一的非负整数的异常号。异常号是到异常表中的索引。
异常类似于过程调用,但有一些重要的不同之处。
一旦硬件触发了异常,异常处理程序则由软件完成。
3、异常的类别——中断、陷阱、故障和终止
- a)中断处理:异步是指硬件中断不是由任何一条指令造成的,而是由外部I/O设备的事件造成的。
- b)陷阱和系统调用:系统调用是一些封装好的函数,内部通过指令int n实现。
陷阱最重要的用途是提供系统调用。系统调用运行在内核模式中,并且可以访问内核中的栈。
系统调用的参数是通过通用寄存器而不是栈来传递的,如,%eax存储系统调用号,%ebx,%ecx,%edx,%esi,%edi,%ebp最多存储六个参数,%esp不能用,因为进入内核模式后,会覆盖掉它。
- c)故障
- d)终止
二、进程(操作系统层):逻辑控制流,私有地址空间,多任务,并发,并行,上下文,上下文切换,调度。
进程就是一个执行中的程序实例。系统中的每个程序都是运行在某个进程的上下文中的。进程提供给应用程序的关键抽象:a)一个独立的逻辑控制流 ;b)一个私有的地址空间
1、逻辑控制流
程序计数器(PC)值的序列叫做逻辑控制流,简称逻辑流。如下图所示,处理器的一个物理控制流分成了三个逻辑流,每个进程一个。
一些概念:并发流:并发流一个逻辑流的执行在时间上与另一个流重叠,叫做~
- 并发:多个流并发执行的一般现象称为并发。
- 多任务:多个进程并发叫做多任务。
- 并行:并发流在不同的cpu或计算机上,叫~
2、私有地址空间
一个进程为每个程序提供它自己的私有地址空间。运行应用程序代码的进程初始时是在用户模式中的。进程从用户模式变为内核模式的唯一方法是通过异常。
linux提供了/proc文件系统,它允许用户模式进程访问内核数据结构的内容。
3、上下文切换,调度
- 上下文切换:操作系统内核使用叫上下文切换的异常控制流来实现多任务。
上下文切换:
a)保存当前进程的上下文;
b)恢复某个先前被抢占的进程被保存的上下文;
c)将控制传递给这个新恢复的进程 - 调度:内核中的调度器实现调度。
当内核代表用户执行上下文切换时,可能会发生上下文切换。如果系统调用发生阻塞,那么内核可以让当前进程休眠,切换到另一个进程,如read系统调用,或者sleep会显示地请求让调用进程休眠。一般,即使系统调用没有阻塞,内核亦可以决定上下文切换,而不是将控制返回给调用进程。中断也可能引起上下文切换。如,定时器中断。
4、进程控制
- 获取进程ID:
创建和终止进程:进程的三种状态——运行、停止和终止。进程会因为三种原因终止进程:收到信号,该信号默认终止进程;从主程序返回;调用exit函数。
父进程通过调用fork创建一个新的运行子进程:父进程与子进程有相同(但是独立的)地址空间,有相同的文件藐视符集合。
- 回收子进程:
回收:当一个进程终止时,内核并不立即把它从系统中清除。相反,进程被保持在一种已终止的状态中,直到被它的父进程回收。
僵死进程:一个终止了但是还未被回收的进程称为僵死进程。
回收子进程的两种方法:
1,内核的init进程 2,父进程waitpid函数
1)如果父进程没有回收它的僵死子进程就终止了,那么内核就会安排init进城来回收它们。init进程的PID为1,并且是在系统初始化时创建的。 2)一个进程可以通过调用waitpid函数来等待它的子进程终止或停止。
waitpid函数有点复杂,默认地(当options=0时),waitpid挂起调用进程的执行,知道它的等待集合中的一个子进程终止。
- wait函数:
wait(&status)函数,等价于调用wait(-1,&status,0)
让进程休眠:sleep函数将一个进程挂起一段指定的时间。
pause函数让调用函数休眠,知道该进程收到一个信号。
加载并运行程序:
环境数组操作函数:
课后作业
进程A和B是互相并发的,就像B和C一样,因为它们各自的执行是重叠的,也就是一个进程在另一个进程结束前开始。进程A和C不是并发的,因为它们的执行没有重叠;A在C开始之前就结束了。
A.这里的关键点是子进程执行了两个prin七f语句。在fork返回之后,它执行了第8行的prin七fe然后它从if语句中出来,执行了第9行的printf语句。下面是子进程产生的输出:printfl:x=2 printf2: x=1
B.父进程只执行了第9行的printf:printf2: x=0
练习8.3列出下面程序所有可能的输出序列:
int main()
{
if(Fork()==0)
{
printf("a"),fflush(stdout);
}
else
{
printf("b"),fflush(stdout);
waitpid(-1,NULL,0);
}
printf("c"),fflush(stdout);
exit(0)
}
父进程调用fork()函数后,子进程满足if中的条件,会打印a,然后打印c;而父进程会执行b,挂起等待子进程终止。打印的最后一项是父进程的c。
子进程直接执行完成,则输出为acbc;父进程先执行后挂起等待子进程执行完成,则输出为bacc;子进程执行后父进程执行,则输出为abcc。
A.每次我们运行这个程序,就会产生6个输出行。
B.输出行的顺序根据系统不同而不同,取决于内核如何交替执行父子进程的指令。一般而言,满足下图的任意拓扑排序都是合法的顺序:
答:
答:
答:
只要休眠进程收到一个未被忽略的信号,sleep函数就会提前返回。但是,因为收到一个SIGINT信号的默认行为就是终止进程(见图8-25 ),我们必须设置一个SIGINT处理程序来允许sleep函数返回。处理程序简单地捕获SIGNAL,并将控制返回给sleep函数,该函数会立即返回。
上周错题总结
实验3中,在Ubuntu虚拟机中编译多线程程序时,gcc使用()选项
A .
-g
B .
-lthread
C .
-pthread
D .
-lpthread
正确答案: C 你的答案: D
实际环境中只有-pthread可用
实验1:mount -t nfs -o nolock 192.168.0.56:/root/share /host,其中的IP是()的IP
A .
Windows 宿主机
B .
Ubuntu虚拟机
C .
ARM实验箱
D .
以上都不对
正确答案: B 你的答案: C
嵌入式开发中,通过nfs系统把Ubuntu虚拟机的一个目录映射成ARM实验箱的Linux系统的一个目录进行调试是一个惯用法,程序调试没有问题了,再烧写到实验箱的Linux的系统中,这样实验箱重启了程序也可以用了。
有关套接字接口函数open_clientfd()、open_listenfd(),下面说法正确的是()
A .
这两个函数中open_clientfd()只可以用于客户端编程
B .
这两个函数中open_clientfd()可以用于客户端和服务器端编程
C .
这两个函数中open_listenfd()只可以用于服务器端编程
D .
open_clientfd()中的port参数是客户端的端口
E .
open_clientfd()中的port参数是服务器端的端口
F .
open_clientfd()返回的clientfd可以有Unix I/O接口读写
G .
open_listenfd()返回的listenfd可以有Unix I/O接口读写
正确答案: A C E F 你的答案: A B D G
p660
有关socket 接口中的connect(),下面说法正确的是()
A .
这个函数用于客户端编程
B .
这个函数用于服务器端编程
C .
调用connect会发生阻塞,连接成功程序会继执行
D .
调用connect()成功返回的文件描述符可以用来数据传输
正确答案: A C D 你的答案: A B D
p654