• 20145234黄斐《信息安全系统设计基础》第十三周学习总结


    课程内容总结

    并发:逻辑控制流在时间上是重叠的

    基于进程的并发编程

    例如:在父进程中接受客户端请求,然后创建新的子进程来为每个客户端服务。

    • 假设我们有两个客户端和一个服务器,服务器正在监听一个监听表述符上的请求。现在假设服务器接受了客户端1的连接请求。
    • 基于进程的并发服务器:
      1. 需要包括一个SIGCHID处理程序,来收回将死进程。
      2. 父子进程必须关闭它们各个的connfd拷贝。
      3. 因套接字的文件表项中的引用计数,直到父子进程的connfd都关闭了,到客户端的连接才会终止。

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

    • 使用select函数,要求内核挂起进程,只有在一个或多个I/O事件发生后,才将控制返回给应用程序。
    • select函数处理类型为fd_set的集合,也叫做描述符集合,并在逻辑上描述为一个大小为n的位向量:b_n-1,...b_1,b_0*

    • 描述符:

      1. 分配他们
      2. 将一个此种类型的变量赋值给另一个变量
      3. 用FD_ZERO、FD_SET、FD_CLR和FD_ISSET宏指令来修改和检查它们
    • 基于I/O多路复用的并发事件驱动服务器

      1. 比基于进程的设计给了程序员更多的对程序行为的控制。

      2. 一个基于I/O多路复用的事件驱动服务器是运行在单一进程上下文中的,因此每个逻辑流都能访问该进程的全部地址空间。,使得在流之间共享数据变得容易。

      3. 事件驱动设计常常比基于进程的设计要高效得多,因为它们不需要进程上下文切换来调度新进程。

    基于线程的并发进程

    • 这是上面两种方法的混合,结合了上面两种方法的特性。

      1. 和进程一样,由内核调度,并内核通过一个整数ID来识别线程。
      2. 同基于I/O多路复用的流一样,多个线程运行在单一进程的上下文中。因此共享这个进程的虚拟地址空间的整个内容:代码啊,数据,堆,共享库和打开文件。
    • 线程就是运行在进程上下文中的逻辑流。
    • 每个线程都有自己的线程上下文,包括:

      1. 一个唯一的整数线程ID
      2. 栈指针
      3. 程序计数器
      4. 通用目的寄存器
      5. 条件码
    • 所有运行在一个进程里的线程共享该进程的整个虚拟地址。
    • 主线程:每个进程开始生命周期时都是单一线程,这个线程称为主线程,它是是进程中第一个运行的线程。
    • 对等线程:被主线程创建,后与主线程并发运行。
    • 对等(线程)池:一个线程可以杀死它的任何对等线程,或等待它的任何对等线程终止。每个对等线程都能读写相同的共享数据。
    • Posix线程:线程代码和本地数据都被封装在一个线程例程中。每个线程都以一个通用指针作为输入,并返回一个通用指针。
    • 创建线程:线程调用pthread_create函数来创建其他线程。
    • 终止线程

      1. 顶层的线程返回,隐式终止。
      2. 调用pthread_exit函数,显示终止。(会等待所有其他对等线程终止,然后再终止主线程和整个进程,返回thread return)
      3. 某个对等线程调用Unix的exit函数,该函数终止进程以及所有与该进程相关的线程。
      4. 另一个对等线程以当前线程ID作为参数调用pthread_cancle终止当前进程。
    • 线程调用pthread_join函数等待其他线程终止。这个函数会阻塞,直到线程tid终止,将线程例程返回的(void*)指针赋值为thread_return指向的位置,然后回收已终止线程占用的所有存储器资源.
    • 分离线程:在任何一个时间点上,进程是可结合的或分离的。
    • 初始化进程:调用pthread_once来初始化与线程的相关状态;

    多线程程序中的共享变量

    • 根据存储类型被映射到虚拟存储器。
    1. 全局变量。函数以外的变量。运行时,虚拟存储器的读/写区域只包含每个全局变量的 一个实例,任何线程可用。
    2. 本地自动变量定义在函数内部没有static属性的变量。运行时,每个线程都含有自己的所有本地自动变量实例
    3. 本地静态变量。在函数内部,有static。和全局变量一样,虚拟存储器的读/写区域只包含在程序中声明的本地静态变量的一个实例。
    • 共享变量:说一个变量v是共享的,当且仅当它的一个实例被一个以上的线程引用。
    • 进度图

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

      将指令执行模型为一种状态到另一种状态的转换。

      合法转换:向右或向上。

      点(L1,S2)对应线程完成L1,而线程2完成S2状态

    • 信号量:是用信号量解决同步问题,信号量s是具有非负整数值的全局变量,有两种特殊的操作来处理,称为P和V:

      1. P(s):如果s非零,那么P将s减1,并且立即返回。

      2. V(s):V操作将s加1,并重启一个阻塞的线程

    • 使用信号量来实现互斥:将每个共享变量(或者一组相关的共享变量)与一个信号量s(初始为1)联系起来,然后用P(s)和V(s)操作将相应的临界区包围起来。
    • 利用信号量来调度共享资源
      1. 生产者-消费者问题:因为插入和取出项目都涉及更新共享变量,所以要保证:对缓冲区的访问是互斥的。

      2. 读者-写者问题:修改对象的线程叫做写者;只读对象的线程叫做读者。写者必须拥有对对象的独占访问,而读者可以和无限多个其他读者共享对象。

    • 基于预防线程话的并发服务器
    • 使用线程提高并行性:多核处理可以并行。

    其他并发问题

    • 不安全函数类

      1. 不保护共享变量的函数
      2. 保持跨越多个调用的状态的函数
      3. 返回指向静态变量的指针的函数
      4. 调用线程不安全函数的函数
    • 可重入函数:被多个线程调用时,不会引用任何共享数据。(是线程安全函数的一个真子集)
      1. 显式可重入的:所有函数参数都是传值传递,没有指针,并且所有的数据引用都是本地的自动栈变量,没有引用静态或全剧变量。

      2. 隐式可重入的:调用线程小心的传递指向非共享数据的指针。

    • 竞争: 程序员假定线程会按照某种特殊的轨迹穿过执行状态空间,忘了一条准则规定:线程化的程序必须对任何可行的轨迹线都正确工作。
    • 死锁:一组线程被阻塞了,等待一个永远也不会为真的条件。

  • 相关阅读:
    Linux命令选项及参数解析 getopt() getopt_long() 函数
    找不到文件或程序集名称“DreamweaverCtrls”的解决方法
    #include file 与#include virtual的区别
    用dw(dreamweaver)开发asp.net,连接数据库时出现“http错误500,服务器内部错误”的解决方法
    [ASP.Net]ASP.NET中上传文件
    [.net]"Request.Form出现乱码"的解决方法
    正式进驻博客园
    [ASP.NET] 限制上传文件类型的两种方法(转)
    错误类型:“系统找不到 Microsoft.Office.Interop.Word"
    从客户端检测到有潜在危险的Request.Form 值
  • 原文地址:https://www.cnblogs.com/taigenzhenjun/p/6160429.html
Copyright © 2020-2023  润新知