20145308 《信息安全系统设计基础》第13周学习总结

20145308 《信息安全系统设计基础》第13周学习总结

教材学习内容总结

视频学习

  • 接口:指明模块要做什么
  • 实现:指明模块如何完成接口
  • 函数签名:函数名、参数个数、返回值
  • 万能函数
  • 并发:程序级并发(进程)、函数级并发(线程)

第12章 并发编程

  • 构造并发程序的方法
    • 进程:每个逻辑控制流都是一个进程,由内核来调度和维护,有独立的虚拟地址,使用某种显式的进程间通信机制
    • I/O多路复用:应用程序在一个进程的上下文中显式地调度他们自己的逻辑流,共享地址空间
    • 线程:运行在单一进程上下文中的逻辑流,由内核进行调度,共享单一虚拟地址

12.1 基于进程的并发编程

  • 构造并发服务器:父进程中接受客户端连接请求,然后创建一个新的子进程来为每个新用户端提供服务
12.1.1 基于进程的并发服务器
  • 因为通常服务器会运行很长时间,所以需要一个SIGCHLD处理程序,来回收僵死进程。因为当SIGCHLD执行时,信号是阻塞的,而UNIX信号是不排队的,所以SIGCHLD必须准备好回收多个僵死进程。另外注意,循环中的父进程和子进程关闭各自需要关闭的描述符。
12.1.2 关于进程的优劣
  • 进程能够共享文件表,但不共享用户地址空间

12.2 基于I/O多路复用的并发编程

  • I/O多路复用技术。基本思想是,使用select函数,要求内核挂起进程,只有在一个或多个I/O事件发生后,才将控制返回给应用程序
12.2.1 基于I/O多路复用的并发时间驱动服务器
  • I/O多路复用可以用做并发事件驱动程序的基础,在事件驱动程序中,流是因为某种事件而前进的,一般概念是把逻辑流模型化为状态机。一个状态机就是一组状态、输入事件和转移。
  • 并发事件驱动程序中echo服务器中逻辑流的状态机
12.2.2 I/O多路复用技术的优劣
  • 优点:给了程序员更多的对程序行为的控制、流之间共享数据容易
  • 缺点:编码复杂

12.3 基于线程的并发编程

  • 线程:运行在进程上下文中的逻辑流
  • 线程由内核自动调度,每个线程都有它自己的线程上下文
12.3.1 线程执行模型
  • 每个进程开始生命周期时都是单一线程,这个线程称为主线程
  • 在某一时刻,主线程创建一个对等线程,从在此刻开始,两个线程就并发地运行
  • 和一个进程相关的线程组成一个对等(线程)池,独立于其他线程创建的线程
  • 对等(线程)池党的重要概念:一个线程可以杀死它的任何对等线程,或者等待它的任意对等线程终止
  • 每个对等线程都能读写相同的共享数据
12.3.2 Posix线程
  • Posix线程(Pthreads)是在C程序中处理线程的一个标准接口
  • 允许程序创建、杀死和回收线程,与对等线程安全地共享数据,还可以通知对等线程系统状态的变化
12.3.3 创建线程
  • 通过调用pthread_create函数来创建其他线程
  • 新线程可以通过pthread_self函数来获得它自己的线程ID
12.3.4 终止线程
  • 有以下四种方式终止线程:

     当顶层的线程例程返回时,线程会隐式终止;
    
     线程调用`pthread_exit`函数,线程会显示终止;如果主线程调用`pthread_exit`,它会等到所有其他对等线程终止,然后再终止主线程和整个线程,返回值为`thread_return`;
    
     某个对等线程调用`exit`函数,则函数终止进程和所有与该进程相关的线程;
    
     另一个对等线程调用以当前ID为参数的函数`ptherad_cancel`来终止当前线程
    
12.3.5 回收已终止线程的资源
  • pthread_join函数会终止,直到线程tid终止。和wait不同,该函数只能回收指定id的线程,不能回收任意线程
12.3.6 分离线程
  • 一个可结合的线程能够被其他线程回收其资源和杀死,在被其他线程回收之前,它的存储其资源是没有被释放的
  • 相反,一个分离的线程是不能被其他线程回收或杀死的。它的存储器资源是在它终止时系统自动释放的
12.3.7 初始化线程
  • pthread_once函数允许初始化与线程例程相关的状态
12.3.8 一个基于线程的并发服务器

12.4 多线程程序中的共享变量

12.4.1 线程存储器模型
  • 每个线程都有它自己独自的线程上下文,包括线程ID、栈、栈指针、程序计数器、条件码和通用目的寄存器值
  • 每个线程和其他线程一起共享进程上下文的剩余部分
  • 寄存器是从不共享的,而虚拟存储器总是共享的
12.4.2 将变量映射到存储器
  • 线程化的c程序中变量根据它们的存储器类型被映射到虚拟存储器:全局变量,本地自动变量(不共享),本地静态变量
  • 全局变量:定义在函数之外的变量。虚拟存储器的读/写区域只包含每个全局变量的一个实例,任何线程都可以引用
  • 本地自动变量:定义在函数内部但没有static属性的变量
  • 本地静态变量:定义在函数内部并有static属性的变量
12.4.3 共享变量
  • 共享:当且仅当它的一个实例被一个以上的线程引用

12.5 用信号量同步线程

12.5.1 进度图
  • 进度图
  • 不安全区:两个临界区的交集形成的状态安全区域
12.5.2 信号量
  • 信号量:是用信号量解决同步问题,信号量s是具有非负整数值的全局变量,有两种特殊的操作来处理(P和V)
  • P(s):如果s非零,那么P将s减1,并且立即返回。如果s为0,那么就挂起这个线程,直到s变为非零
  • V(s):V操作将s加1
12.5.3 使用信号量来实现互斥
  • 二元信号量:用P和V操作将相应的临界区包围起来的方式来保护共享变量的信号量
  • 互斥锁:以提供互斥为目的的二元信号量
12.5.4 利用信号量来调度共享资源
  • 生产者——消费者问题:必须保证对缓冲区的访问是互斥的;还需要调度对缓冲区的访问,即,如果缓冲区是满的(没有空的槽位),那么生产者必须等待直到有一个空的槽位为止,如果缓冲区是空的(即没有可取的项目),那么消费者必须等待直到有一个项目变为可用
  • 读者——写者问题:修改对象的线程叫做写者;只读对象的线程叫做读者。写着必须拥有对对象的独占访问,而读者可以和无限多个其他读者共享对象。读者——写者问题基本分为两类:第一类,读者优先,要求不要让读者等待,除非已经把使用对象的权限赋予了一个写者。换句话说,读者不会因为有一个写者等待而等待;第二类,写者优先,要求一定能写者准备好可以写,它就会尽可能地完成它的写操作。同第一类问题不同,在一个写者后到达的读者必须等待,即使这个写者也是在等待
12.5.5 综合:基于预线程化的并发服务器
  • 使用预线程化技术的并发服务器:服务器是由一个主线程和一组工作组线程构成的。主线程不断地接受来自客户端的连接请求,并将得到的连接描述符放在一个有限缓冲区中。每一个工作组线程反复地从共享缓冲区中取出描述符,为客户端服务,然后等待下一个描述符

12.6 使用线程提高并行性

12.7 其他并发问题

12.7.1 线程安全
  • 四种不安全函数
    • 不保护共享变量的函数
    • 保持跨越多个调用状态的函数
    • 返回指向静态变量的指针的函数
    • 调用线程不安全函数的函数
12.7.2 可重入性
  • 可重入函数:可重入函数是线程安全函数的一个真子集,它不访问任何共享数据。可重入安全函数通常比不可重入函数更有效,因为它们不需要任何同步原语。
12.7.3 在线程化的程序中使用已存在的库函数
12.7.4 竞争
  • 竞争:当程序员错误地假设逻辑流该如何调度时,就会发生竞争。为了消除竞争,通常我们会动态地分配内存空间。
12.7.5 死锁
  • 死锁:当一个流等待一个永远不会发生的事件时,就会发生死锁

第11章 网络编程

11.1 客户端——服务器编程模型

  • 每个网络应用都是基于客户端-服务器模型

11.2 网络

  • 以太网段:包括一些电缆和集线器
  • 桥接以太网:使用一些电缆和网桥,多个以太网连接成的较大局域网
  • internet互联网络:多个不兼容的局域网通过路由器连接
  • 协议消除了不同网络之间的差异

11.3 全球IP因特网

  • 每台因特网主机上都运行实现TCP/IP协议
11.3.1 Ip地址
  • 网络字节顺序:大端字节法
11.3.2 因特网域名
  • gethostbynamegethostbyaddr函数,从DNS库中检索任意主机条目
11.3.3 因特网连接
  • 因特网客户端和服务器通过在连接上发送和接收字节流来通信

11.4 套接字接口

  • 套接字接口:一组函数,与Unix I/O函数结合起来,用以创建网络应用
11.4.1 套接字地址结构
  • 从Unix程序的角度来看,套接字就是一个有相应描述符的打开文件
11.4.2 socket函数
  • 服务器和客户端使用socket函数创建套接字描述符
11.4.3 connect函数
  • 客户端调用connect函数来建立和服务器的连接
11.4.4 open_clientfd函数
11.4.5 bind函数
  • 服务器用来和客户端建立连接
  • bind函数将my_addr中的服务器套接字地址和套接字描述符sockfd连接起来
11.4.6 listen函数
  • sockfd从一个主动套接字转化为一个监听套接字
11.4.7 open_listenfd函数
11.4.8 accept函数
  • 服务器等待来自客户端的请求
11.4.9 echo客户端和服务器的示例

11.5 web服务器

11.5.1 web基础
  • web客户端与服务器交互用基于文本的应用级自协议HTTP
11.5.2 web内容
  • 服务静态内容:读取磁盘内容返回客户端
  • 服务动态内容:运行可执行文件并输出结果
11.5.3 HTTP事务
  • 1.HTTP请求
  • 2.HTTP响应
11.5.4 服务动态内容

11.6 综合:TINY Web服务器

本周代码托管截图

https://git.oschina.net/yg1022/CSAPP2E.git

其他

  • 本周学习了11、12两章的内容,11章是网络编程的内容,但是和老师课程的内容有一些不一样,学习时主要注意了不同的部分。12章学习了并发编程,主要学习了三种方法,减少程序的运行时间。本周内容还是有些多的,希望自己下周能早点开始完成任务

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 0/0 1/2 25/30 学习Linux指令
第二周 50/50 1/3 25/55 Linux系统下的开发环境
第三周 20/70 1/4 25/80 信息的表示和处理
第五周 20/90 1/5 30/110 程序的机器级表示
第六周 20/110 1/6 30/140 处理器体系结构
第七周 20/130 1/7 30/170 存储器层次结构
第八周 0/130 2/9 10/180 期中复习
第九周 48/178 2/11 10/190 系统级I/O、错误处理
第十周 539/717 2/13 10/200 系统调用学习
第十一周 429/1146 2/15 10/210 异常控制流
第十二周 20/1166 3/18 10/220 第九、十、十一周代码
第四周 1174/2340 1/19 10/230 网络编程、并发编程
posted @ 2016-12-10 19:12  20145308刘昊阳  阅读(130)  评论(1编辑  收藏  举报