2017-2018-1 20155306 《信息安全系统设计基础》第6周学习总结
教材学习内容总结
第八章 异常控制流
具体函数的应用详见2017-2018-1 20155306 《信息安全系统设计基础》Mybash的实现
1.异常:控制流的突变,响应处理器的某些变化。通过一张由处理器设计者和操作系统定义的异常表跳转到异常处理程序。IA32异常表包括256种异常,通过基址寄存器和异常号*4得到条目地址。
2.异常种类:中断,陷阱,故障,终止
a) 陷阱是执行一条指令的结果,最重要的用途就是提供系统调用。
b) 故障示例:缺页异常。发生该异常,缺页处理程序处理后,重新执行产生故障的指令。
c) C程序用syscall执行系统调用(汇编代码int $0x80),也可以直接使用C标准库的包装函数。
3.进程:一个执行中程序的实例。每个程序运行在某个进程的上下文(程序正确运行所需要的状态,包括用户栈,内核栈,PC,PATH,内核数据结构等)中,进程提供了2个重要的抽象:逻辑控制流和私有的地址空间。
-
并发流:一个逻辑流的执行在时间上与另一个重叠。并行表示并发地运行在不同处理器。
-
处理器通过某个控制寄存器的模式位提供用户模式和内核模式的切换。
-
pid_twaitpid(pid_t pid, int *status, int options);
a)pid大于0,等待集合为单独子进程。pid小于0,等待集合为父进程所有子进程。
b) 最后一个参数设置为0,表明阻塞到有子进程终止。
c) 成功返回子进程PID,若为WNOHANG | WUNTRACED非阻塞,若等待集合中没有任何子进程被停止或终止,立即返回0,或返回被停止或已终止子进程PID
-
unsignedint sleep(unsigned int secs); //请求时间到返回0,若因信号中断过 早返回,返回剩余的秒数。
-
intpause(void); //总是返回-1,让进程休眠,直到遇到一个信号。
-
intexecve(const char *filename, const char *argv[],
const char *envp[]); //在当前进程上下文中加载运行一个新程序。 -
kill-9 -15213 为 负的PID导致信号被发到进程组PID每个进程。
-
ls| sort创建一个两个进程组成的前台作业(同属一个进程组),通过管道连接起来。
-
intkill(pid_t pid, int sig); //发送信号sig给进程pid,pid<0发送给abs(pid)中每个进程。
-
unsignedint alarm(unsigned int secs); //对alarm的调用将取消任何待处理闹钟,并返回剩余的秒数
-
typedefvoid (*sighandler_t)(int);
sighandler_tsignal(int signum, sighandler_t handler);
a) Returns:ptr to previous handler if OK, SIG_ERR on error (does not set errno)
b) handler可以设置为忽略signum的信号SIG_IGN,或者默认行为SIG_DFL,或者为自定义行为。
c) 同类型的一个待处理信号被阻塞,直到前一个处理程序返回。不会排队等待,只是简单的丢弃。且慢速系统调用可被中断,有时不会主动重启而返回EINTR错误。
-
可以通过诸如intsigprocmask(int how, const sigset_t *set, sigset_t *oldset);的函数改变已阻塞信号的集合,可以用作同步解决竞争问题。
-
暴露代码竞争的方法:用随机的方法确定子进程或者父进程任一个休眠一会儿。
-
int setjmp(jmp_buf env); int sigsetjmp(sigjmp_buf env, intsavesigs);
非本地跳转其中一个应用就是深层嵌套中发现错误,返回到错误处理处。 -
void longjmp(jmp_buf env,int retval); voidsiglongjmp(sigjmp_buf env, int retval);
这2个函数的版本是可以被信号处理函数使用的版本,使得信号处理程序分支能到达特殊的位置。
第十章 系统级I/O
1.size_t表unsigned int
ssize_t表int
2.intopen(char *filename, int flags, mode_t mode);
Returns: 若成功则为新文件描述符,若出错为-1;
int close(intfd);
Returns: 若成功则为1,若出错则为-1.
- ssize_tread(int fd, void *buf, size_t n);
Returns: 若成功则为写的字节数,若出错为-1
ssize_twrite(int fd, const void *buf, size_t n);
Returns: 若成功则为写的字节数,若出错为-1
以上两个函数有时会返回一个不足值,如EOF,从终端读文本行,读写socket。
4.常常采用自己封装的带缓冲区的输入输出函数。C标准I/O库将一个打开的文件模型化为一个流,使得开销较高的UnixI/O系统调用的数量尽可能小。主要完成:
a)确保指定的n个数据全部接收发送完成。
b) 将接收到的数据存入自己定义的一个缓冲区
5.获取文件状态 int stat(const char*filename, struct stat *buf);
int fstat(int fd, struct stat *buf);
Returns: 若成功则为1,若出错则为-1.
6.子进程如何继承父进程的打开文件:
描述符不同,打开文件表、v-node表就不同。
父子进程共享同一个描述符,故后面两个表都相同。
7.将newfd重定向到oldfd:
intdup2(int oldfd, int newfd);
Returns:若成功则为非负的描述符若出错则为-1
8.对网络套接字,不要用标准I/O进行输入输出。使用sprintf格式化字符,再发送。
使用sscanf对文本提取不同的字段。
教材学习中的问题和解决过程
- 问题1课后习题10.5中答案并不是'f'
- 解决:通过课后讲解,发现本题在fd1是fd2的复制品,也就是两个文件描述符都指向一个文件,重定位后,文件的引用计数也要加一,答案是'o'
代码调试中的问题和解决过程
-
问题1:练习书上10.1代码时,出现如下情况:
-
解决:通过百度和学长的博客明白,缺少csapp.h的头文件,这是书的作者编写的一个头文件,使用的时候要把此头文件csapp.h和csapp.c文件包含到你的系统中。先到网上下载这两个文件,下载地址(http://download.csdn.net/detail/tzasd89812/4206284)。
-
由于csapp.c中包含线程的一部分,所以编译的时候要加上-lpthread选项,否则很多错误,然后成功运行。
代码托管
(statistics.sh脚本的运行结果截图)
上周考试错题总结
其他(感悟、思考等,可选)
本周学习了异常控制流以及系统级I/O,利用linux提供的少量的系统级函数允许对文件进行相关操作,处理数据。本周学习任务对我来说有点多,除了学习新内容还需要学习课上未完成的任务。有些书上的代码没有敲完,想要深入理解,还需要更多的时间去好好学习代码。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 20/20 | 1/2 | 10/15 | 第一章 |
第三周 | 130/210 | 1/2 | 21/36 | 第二章 |
第四周 | 70/ 280 | 1/4 | 10/46 | 第十章 |
第五周 | 91 / 371 | 1/6 | 23/69 | 第三章 |
第六周 | 308 / 648 | 1/8 | 31/100 | 第八、十章 |
尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
耗时估计的公式
:Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。
-
计划学习时间:31小时
-
实际学习时间:20小时
-
改进情况:
(有空多看看现代软件工程 课件
软件工程师能力自我评价表)