信息安全系统设计基础第十二周学习总结

第十二章 并发编程

并发指逻辑控制流在时间上是重叠的
进程

  • 每个控制流都是一个进程
  • 是由内核来调度维护
  • 有独立的虚拟地址空间
  • 在与其他流进行通信时,控制流必须使用某种显式的进程间通信机制
    I/O多用复路
  • 在并发编程中,应用程序在一个进程的上下文中显式的调度它们自己的逻辑流
  • 所有流都共享同一个地址空间
    线程
  • 是运行在单一进程上下文中的逻辑流
  • 由内核进行调度
  • 是进程和I/O多用复路的混合体

基于进程的并发编程

基于进程的并发服务器

由于服务器运行时间长,所以要包括一个SIGCHLD进程程序,用来回收僵死子进程的资源

关于进程的优劣

对于父,子进程:共享文件表,但不共享用户地址空间

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

基本思路:使用select函数,要求内核挂起进程,只有在一个或多个I/O事件发生后,才将控制返回应用的程序
例如:

select函数处理类型为fd_set的集合
被允许对描述符集合做的三件事:

  1. 分配他们
  2. 将一个此种类型的变量赋值给另一个变量
  3. 用FD_ZERO,FD_SET,FD_CLR和FD_ISSET宏指令来修改和检查他们
    select的两个输入:
  4. 读集合的描述输入(fdset)
  5. 读集合的基数(n)
    副作用:select修改了参数fdset指向的fd_set,指明读集合中一个称为准备好集合的子集

利用select实现一个迭代echo服务器:


一旦select返回,就用FD_ISSET宏指令来判断哪个可以进行读了

基于I/O多用复路的并发事件驱动服务器

一个状态机就是一组状态输入事件转移,其中转移就是将状态和输入事件映射到状态
自循环同一个输入和输出之间的转换

  • select函数检测到输入事件
  • add_client函数创建一个新的逻辑流
  • check_clients函数通过回送输入行来执行状态转移

服务器使用I/O多用复,借助select函数检测输入事件的发生

clientfd数组表示已连接描述符的集合,其中整数-1表示一个可用的槽位

I/O多用复路技术的优劣:

优点:

  1. 它比基于进程的设计给程序员更多的对程序行为的控制
  2. 一个基于I/O多用复路用事件驱动服务器是运行在一个单一进程上下文,并每个逻辑流都能访问该进程的全部地址空间
    缺点:
  • 编码复杂

基于线程的并发编程

每个线程都有它自己的线程上下文,包括一个唯一的整数线程ID,栈,栈指针,程序计数器,通用目的寄存器和条件码

线程执行模型

主线程:每个进程开始生命周期都是单一线程
某时刻,主线程创建一个对等线程,从此时开始,两个线程并发运行

线程和进程的区别:

  • 一个线程的上下文比一个进程的上下文小很多
  • 线程上下文的切换要比进程上下文的切换快很多
  • 进程是按照严格的父子层次来组织的,线程则是对等的池

Posix线程

  • 创建线程

  • 终止线程

  1. 当顶层的线程例程返回时,线程会隐式地终止
  2. 通过调用pthread_exit函数,线程会显式地终止
  3. 某个对等线程调用Unix的exit函数,该函数终止进程以及与该进程相关的所有线程
  4. 另一个对等线程通过当前线程ID作为参数调用pthread_cancle函数来终止当前线程
  • 回收已终止线程的资源

    pthread_join函数会堵塞,直到线程tid终止,将线程例程返回的(void)指针赋值为pthread_return指向的位置,然后回收*已终止线程占用的所有储存器资源

  • 分离线程
    在任意一个时间点上,线程是可结合的或者是分离的

  • 初始化线程

多线程程序中的共享变量

通常,线程的寄存器是从不共享的,而虚拟储存器总是共享的

将变量映射到存储器

  • 全局变量:是定义在函数之外的变量,任何线程都可以引用
  • 本地自动变量:是定义在函数内部但是没有static属性的变量
  • 本地静态变量:是定义在函数内部并有static属性的变量

共享变量

若说变量v是共享的,当且仅当它的一个实例被一个以上的线程引用

用信号量同步线程

在共享变量的同时引入了同步错误的可能性
一般而言,没有办法预测操作系统是否能为你的线程选择一个正确的顺序

进度图

进度图将n个并发线程的执行模型化为一条n维笛卡尔空间中的轨迹线

图的原点对应于没有任何线程完成一条指令的初始状态


在进度图中,两个临界区的交集形成的状态空间区域称为不安全区

信号量

  • P(s):如果s是非零的,那么P将s减1,并且立即返回。若s为零,则挂起这个线程,直到s非零
  • V(s):V操作将s加1

使用信号量来实现互斥

基本思想:将每个共享变量与一个信号量s联系起来,然后用P(s)和V(s)操作将相应的临界区包围起来

利用信号量来调度共享资源

生产者-消费者问题

基于预线程化的并发服务器

使用线程提高并行性

最简单的方法:将序列划分成t个不相交区域,然后给t个不同的线程每个分配一个区域

并行程序的加速比:


其他并发问题

线程安全

四个线程不安全函数类:

  • 不保护共享变量的函数
  • 保持跨越多个调用的状态的函数
  • 返回指向静态变量指针的函数
  • 调用线程不安全函数的函数

可重入性

在线程化的程序中使用已存在的函数库

竞争

当一个程序的正确性一个线程要在另一个线程到达y点之前到达它的控制流中的x点时,就会发生竞争

死锁


避免死锁的规则:
互斥锁加锁顺序规则:如果对于程序中每对互斥锁(s,t),每个同时占用s和t的线程都按照相同的顺序对它们加锁,那这个程序是无死锁的

posted @ 2015-12-01 10:53  20135330张若嘉  阅读(241)  评论(0编辑  收藏  举报