• 20145314郑凯杰《信息安全系统设计基础》第13周学习总结


    20145314郑凯杰《信息安全系统设计基础》第13周学习总结

    明确教材学习目标

    学习目标

    • 掌握三种并发的方式:进程、线程、I/O多路复用
    • 掌握线程控制及相关系统调用
    • 掌握线程同步互斥及相关系统调用

    教材学习内容总结

    网络编程

    • 客户端-服务器编程模型

      1. 每个网络应用都是基于客户端-服务器模型。
      2. 一个应用是由一个服务器进程和一个或者多个客户端进程组成。
      3. 服务器管理某种资源,并通过操作资源来为客户端提供某种服务。
      4. 基本操作是事务。
    • 四个步骤

      1. 当客户端需要服务时,向服务器发送请求,发起一个事务。
      2. 服务器收到请求后,解释它,并以适当的方式操作它的资源。
      3. 服务器给客户端发送一个响应,并等待下一个请求。
      4. 客户端收到响应并处理它。
    • 每个以太网适配器都有一个全球唯一的48位地址。

    • 每台因特网主机都运行实现TCP/IP协议的软件。

    • 因特网的客户端和服务器混合使用套接字接口函数和Unix I/O函数来进行通信。

    • 套接字接口

    sockaddr_in的16字节结构

    1. sin_family成员是AF_INET
    2. sin_port成员是一个16位的端口号
    3. sin_addr成员是一个32位的IP地址。
    4. IP地址和端口号总时以网络字节顺序(大端法)存放的。
    5. _in是互联网络的缩写,不是输入input的缩写。
    • Web服务器

      Web服务器使用HTTP协议和它们的客户端(浏览器等)彼此通信。

    并发编程

    逻辑控制流在时间上重叠,那么它们就是并发的。并发出现在计算机系统的许多不同层面上。

    使用应用级并发的应用程序称为并发程序。现代操作系统提供了三种基本的构造并发程序的方法:

    1. 进程。每个逻辑控制流都是一个进程,由内核来调度和维护。因为进程 有独立的虚拟地址空间,想要和其他流通信,控制流必须使用某种显式的进程间通信 (interprocess communication, IPC) 机制。
    2. I/O 多路复用。在这种形式的并发编程中,应用程序在一个进程的上下文中显式地调度它们自己的逻辑流。逻辑流被模型化为状态机,数据到达文件描述符后,主程序显式地从一个状态转换到另一个状态。因为程序是一个单独的进程,所以所有的流都共享同一个地址空间。
    3. 线程。线程是运行在一个单一进程上下文中的逻辑流,由内核进行调度。是其他两种方式的混合体,像进程流一样由内核进行调度,而像I/O 多路复用流一样共享同一个虚拟地址空间。
    • 12.1基于进程的并发编程

    1. 构造并发程序最简单的方法就是用进程。
    2. 一个构造并发服务器的自然方法就是,在父进程中接受客户端连接请求,然后创建一个新的子进程来为每个新客户端提供服务。
    • 第一步:服务器接受客户端的连接请求;

    • 第二步:服务器派生一个子进程为这个客户端服务;

    • 第三步:服务器接受另一个连接请求;

    • 基于进程的并发服务器

    • 第四步:服务器派生另一个子进程为新的客户端服务。基于进程的并发 echo 服务器.父进程派生一个子进程来处理每个新的连接请求:

    Posix线程

    Posix线程是C程序中处理线程的一个标准接口。
    

    万能函数:

    void func(void parameter)
    typedef void (uf)(void para)
    

    创建线程

    1.创建线程:

    pthread_create函数

    #include <pthread.h>
    typedef void *(func)(void *);
    

    int pthread_create(pthread_t *tid, pthread_attr_t *attr, func *f, void *arg);

    功能:创建一个新的线程,带着一个输入变量arg,在新线程的上下文运行线程例程f。

    2.查看线程ID

    pthread_self函数
    #include <pthread.h>
    

    pthread_t pthread_self(void);

    功能:返回调用者的线程ID(TID)

    3、终止线程

    1. 终止线程的方式:隐式终止显式终止

    2. pthread_exit函数

       #include <pthread.h>
       void pthread_exit(void *thread_return);
      

    3.pthread_cancle函数

    #include <pthread.h>
    void pthread_cancle(pthread_t tid);
    

    五、回收已终止线程的资源

    pthread_join函数:

    #include <pthread.h>
    

    int pthread_join(pthread_t tid,void **thrad_return);

    六、分离线程

    pthread_detach函数

    #include <pthread.h>
    

    void pthread_detach(pthread_t tid);
    功能:分离可结合线程tid。

    七、初始化线程

    pthread_once函数

    #include <pthread.h>
    pthread_once_t once_control = PTHREAD_ONCE_INIT;
    

    int pthread_once(pthread_once_t once_control, void (init_routine)(void));

    第四节 多线程程序中的共享变量

    1. 线程存储器模型
    2. 将变量映射到存储器
    3. 共享变量

    12.5 用信号量同步线程

    • 进度图

    进度图转换规则:

    • 合法的转换是向右或者向上,即某一个线程中的一条指令完成
    • 两条指令不能在同一时刻完成,即不允许出现对角线
    • 程序不能反向运行,即不能出现向下或向左
    • 而一个程序的执行历史被模型化为状态空间中的一条轨迹线。

    线程循环代码的分解:

    • H:在循环头部的指令块
    • L:加载共享变量cnt到线程i中寄存器%eax的指令。
    • U:更新(增加)%eax的指令
    • S:将%eax的更新值存回到共享变量cnt的指令
    • T:循环尾部的指令块

    临界区使用原则:有空让进、无空等待、多中择一、让权等待

    • 信号量

    信号量定义:

    type semaphore=record
    count: integer;
    queue: list of process
    end;
    var s:semaphore;
    
    • 使用信号量来实现互斥

    第七节 并发问题

    一、线程安全性

    四个不相交的线程不安全函数类以及应对措施:

    不保护共享变量的函数——用P和V这样的同步操作
    保持跨越多个调用的状态的函数——重写
    返回指向静态变量的指针的函数——①重写;②使用加锁-拷贝技术。

    二、可重入性

    1.显式可重入的

    所有函数参数都是传值传递,没有指针,并且所有的数据引用都是本地的自动栈变量,没有引用静态或全剧变量。

    2.隐式可重入的

    调用线程小心的传递指向非共享数据的指针。

    三、竞争

    竞争发生的原因:

    一个程序的正确性依赖于一个线程要在另一个线程到达y点之前到达它的控制流中的x点。也就是说,程序员假定线程会按照某种特殊的轨迹穿过执行状态空间,忘了一条准则规定:线程化的程序必须对任何可行的轨迹线都正确工作。
    消除方法:

    动态的为每个整数ID分配一个独立的块,并且传递给线程例程一个指向这个块的指针
    四、死锁

    一组线程被阻塞了,等待一个永远也不会为真的条件。

    代码上传

    咯咯:

    学习进度条

    代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
    目标 2000行 30篇 400小时
    第九周 832/950 17/17 140/140
    第十周 968/1050 18/18 160/160
    第十一周 1100/1200 19/19 180/180
    第十二周 1197/1300 21/21 200/200

    | 第十三周 | 1300/1400 | 22/22 | 210/210 | |

    参考资料

  • 相关阅读:
    Mysql 批量插入数据的方法
    sql server 多行合并一行
    跨服务器多库多表查询
    OPENQUERY用法以及使用需要注意的地方
    C# 判断操作系统的位数
    rpc介绍
    JavaScript decodeURI()与decodeURIComponent() 使用与区别
    UNIX 时间戳 C#
    C# winform javascript 互调用
    oracle 实例名和服务名以及数据库名区别
  • 原文地址:https://www.cnblogs.com/5314zkj/p/6160357.html
Copyright © 2020-2023  润新知