《信息安全系统设计基础》第11周学习总结
《信息安全系统设计基础》第11周学习总结
教材学习内容
异常
- 事件:在处理器中状态被编码为不同的位和信号。状态变化称为事件。
- 当处理器检测到有事件发生时,会通过异常表跳转到异常处理程序。
- 异常处理程序处理结束之后,会有三种结果:
(1)处理程序将控制返回给事件发生的时候正在执行的指令
(2)处理程序将控制返回给如果没有发生异常将会执行的下一条指令
(3) 处理程序终止被终端的程序
如下图所示为异常的剖析
异常的类型
/proc文件目录
在linux中,/proc用户模式进程访问内核数据结构。在/proc下还有三个很重要的目录:net,scsi和sys。 Sys目录是可写的,可以通过它来访问或修改内核的参数,而net和scsi则依赖于内核配置。一些以数字命名的目录,它们是进程目录。系统中当前运行的每一个进程都有对应的一个目录在/proc下,以进程的 PID号为目录名,它们是读取进程信息的接口。
如下图所示是/proc内容:
查看cpu信息:
上下文切换(调度使用的一种机制)
- 上下文:内核重新启动一个被抢占的进程所需的状态。由一些对象的值组成:、通用目的寄存器、浮点寄存器、程序计数器、用户栈、状态寄存器、内核栈、内核数据结构:页表、进程表、文件表
- 上下文切换
(1)保存当前进程的上下文
(2)恢复某个先前被抢占的进程被保存的上下文
(3)将控制传递给这个新恢复的进程。
fork函数
- 父进程中fork函数返回子进程的pid。
- 子进程中fork函数返回0.
课本p493代码gdb运行,观察pid的变化。调用fork函数后pid=0.子进程结束后才运行父进程。
1、forkdemo1.c函数
1.根据初始输出调用fork函数后pid不为0,得知先返回到父进程,再返回到子进程。
2、forkdemo2.c函数
1.调用两次fork函数,返回四次after
2.gdb单步执行结果:
3、forkdemo3.c
- fork产生子进程,父进程返回子进程pid,不为0,所以输出父进程的那句话,子进程返回0,所以会输出子进程那句话
- 运行如下
4、forkdemo4.c
- 先打印进程pid,然后fork创建子进程,父进程返回子进程pid,所以输出parent一句,休眠十秒;子进程返回0,所以输出child与之后一句
- 运行如下
5、forkgdb.c
- fork函数调用的进程并发执行,并且变量各自是私有的。
- 父进程打印是先打印两句,然后休眠一秒,然后打印一句,子进程先打印一句,然后休眠一秒,然后打印两句。并且这两个线程是并发的,所以可以看到在一个线程休眠的那一秒,另一个线程在执行,并且线程之间相互独立互不干扰
- 运行如下
execve
- 带 p 的exec函数:execlp,execvp,表示第一个参数path不用输入完整路径,只有给出命令名即可,它会在环境变量PATH当中查找命令
1、exec1.c
- execvp函数表示第一个参数path不用输入完整路径,只有给出命令名即可,它会在环境变量PATH当中查找命令
- 执行结果:
2、execv2.c
-
exec2与exec1的区别就在于exevp函数的第一个参数形式不一样,但是参数等价,所以运行结果是相同的
-
若将exevp函数传入的arglist[0]改为arglist[1],此时exevp函数没有调用成功,于是打印出“* * * ls is done. bye”这句话
3、exevc3.c
- 函数中execlp()会从PATH 环境变量所指的目录中查找符合参数file的文件名,找到后便执行该文件,然后将第二个以后的参数当做该文件的argv[0]、argv[1]……最后一个参数必须用空指针(NULL)作结束
wait
wait的函数:
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
进程一旦调用了wait,就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程, wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。
参数status用来保存被收集进程退出时的一些状态,它是一个指向int类型的指针。但如果我们对这个子进程是如何死掉的毫不在意,只想把这个僵尸进程消灭掉,(事实上绝大多数情况下,我们都会这样想),我们就可以设定这个参数为NULL,就象下面这样:
pid = wait(NULL);
如果成功,wait会返回被收集的子进程的进程ID,如果调用进程没有子进程,调用就会失败,此时wait返回-1,同时errno被置为ECHILD。
1、waitdemo1.c的功能是如果有子进程,则终止子进程,成功返回子进程pid。运行如下
2、waitdemo2.c比起1来就是多了一个子进程的状态区分,把状态拆分成三块,exit,sig和core。
testbuf
1、testbuf1.c代码运行如下
2、testbuf2.c代码运行如下
- 使用fflush(out)后,立刻清空输出缓冲区,并把缓冲区内容输出.
3、testbuf3.c将内容格式化输出到标准错误、输出流中
4、testpid.c代码输出当前进程pid和当前进程的父进程的pid
5、testsystem.c代码中system()——执行shell命令,也就是向dos发送一条指令。这里是后面可以跟两个参数,然后向dos发送这两个命令,分别执行
env
getenv函数
1.获得环境变量值的函数
2.参数是环境变量名name,例如”HOME”或者”PATH”。如果环境变量存在,那么getenv函数会返回环境变量值,即value的首地址;如果环境变量不存在,那么getenv函数返回NULL
setenv函数
1.修改或添加环境变量的函数
2.将name设置成value
1、environ。c函数运行结果:
2、environvar.c
简单打印环境变量表
extern char **environ;
每个程序都有一个环境表,它是一个字符指针数组,其中每个指针包含一个以NULL结尾的C字符串的地址。全局变量environ则包含了该指针数组的地址
fifo
-
FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。
-
FIFO严格遵循先进先出(first in first out),对管道及FIFO的读总是从开始处返回数据,对它们的写则把数据添加到末尾。它们不支持诸如lseek()等文件定位操作。
-
FIFO往往都是多个写进程,一个读进程。
1、consumer.c
2、producer.c
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 3500行 | 30篇 | 400小时 | |
第一周 | 40/40 | 1/1 | 20/20 | |
第二周 | 30/70 | 1/2 | 30/50 | |
第三周 | 21/91 | 1/3 | 28/78 | |
第五周 | 131/222 | 1/4 | 20/98 | |
第六周 | 32/254 | 1/5 | 21/119 | |
第七周 | 200/454 | 1/5 | 21/119 | |
第八周 | 0/454 | 2/7 | 10/129 | |
第九周 | 84/538 | 2/9 | 15/144 | |
第10周 | 441/979 | 2/11 | 10/154 | |
第11周 | 460/1439 | 2/13 | 20/174 |