• 8 同步


    并发的好处

    1. 共享资源
      • 一台电脑,多个用户
      • 一个银行取款余额,多台ATM机
      • 嵌入式系统(机器人控制:手臂和手的协调)
    2. 加速
      • I/O操作和计算可以重叠
      • 多处理器 - 将程序分成多个部分并行执行
    3. 模块化
      • 将大程序分解成小程序
      • 使系统容易扩展

    存在的问题

    1. 竞态条件(race condition)

    2. 并发程序共享资源时具有不确定性和不可重现性

    3. 示例:
      image-20200807100831681

      image-20200807100911101

    举例

    image-20200828203053324

    image-20200828203457869

    基本概念

    1. 临界区(Critical Section):进程中一段需要访问共享资源,且当另一进程处于相应代码区域时便不会被执行的代码区域
    2. 互斥(Mutual Exclusion):当一个进程处于临界区并访问共享资源时,没有其他进程会处于临界区并访问任何相同的共享资源
    3. 死锁(Dead Lock):两个或以上的进程,相互等待对方完成特定任务,而最终没法将自身任务进行下去
    4. 饥饿(Starvation):一个可执行进程,被调度器持续忽略,以至于虽处于可执行状态却不被执行

    临界区的属性

    1. 互斥
    2. progress(前进):如果一个线程想进入临界区,那么它最终会成功
    3. 优先等待:如果一个线程 i 处于入口区,那么在 i 的请求被接收之前,其他线程进入临界区的时间是有限制的(线程 i 不会无限等待)
    4. 无忙等待(可选):如果一个进程在等待进入临界区,那么它可以在进入前被挂起(忙等会白白占用系统资源)

    保护临界区的方法(锁机制)

    image-20200831204544694

    禁用硬件中断

    1. 过程
      • 进入临界区时,禁用中断,便没有上下文切换
      • 离开临界区时,重新启动中断
      • 硬件将中断处理延迟到中断启用之后
    2. 不足
      • 一旦中断被禁用,线程无法被停止
        • 整个系统都为你停下来
        • 其他线程可能处于饥饿状态
      • 如果临界区可以任意长怎么办?
        • 无法限制响应中断的时间长短
        • 可能对存在硬件影响
      • 不适用于多CPU的情况。多CPU情况下,禁用一个CPU的中断无法阻止另一个CPU处理中断

    基于软件的解决方案

    1. Peterson算法(双进程)

      • 思考

        • image-20200829101509640
        • image-20200829101609456
        • image-20200829101650415
      • 内容

        int turn; //指示该由谁进入临界区
        boolean flag[]; //指示进程是否准备好进入临界区
        // 进程Pi的算法:
        do{
            flag[i] = TRUE;
            turn = j;
            while(flag[j] && turn == j);
            // Critical Section
            flag[i] = FALSE;
            // Remainder Section
        }while(TRUE);
        
    2. Dekker算法(双进程,较为复杂)
      image-20200829102829240

    3. Eisenberg and McGuire算法(多进程)
      image-20200829102956079

    4. Bakery算法(多进程)
      image-20200829103030103

    5. 不足

      • 复杂:需要多个进程间的共享数据项
      • 忙等浪费CPU时间
      • 需要硬件保证:Peterson算法需要LOAD(内存加载到寄存器)和STORE(寄存器存储到内存)是原子操作

    基于原子操作指令

    1. 现代体系结构大多支持特殊的原子操作指令

      • 通过特殊的内存访问电路
      • 针对单处理器和多处理器
    2. 两个基本的原子操作

      • Test-and-Set 测试和置位

        • 从内存中读取值
        • 测试该值是否为1(然后返回True/False)
        • 将内存值置1
        // 语义
        boolean TestAndSet(boolean *target){
            boolean rv = *target;
            *target = TRUE;
            return rv;
        }
        
      • Exchange 交换

        • 交换内存中的两个值
        // 语义
        void Exchange(boolean *a, boolean *b){
            boolean temp = *a;
            *a = *b;
            *b = temp;
        }
        
    3. 锁的实现

      • TestAndSet

        /* 忙等待:当临界区较长时,占用较多CPU资源 */
        class Lock{
            int value = 0;
        }
        Lock::Acquire(){
            while(test-and-set(value))
                ; //忙等
        }
        Lock::Release(){
            value = 0;
        }
        
        /* 无忙等待:当临界区较短时,上下文切换代价比忙等更大 */
        class Lock{
            int value = 0;
            WaitQueue q;
        }
        Lock::Acquire(){
            while(test-and-set(value)){
            	add this TCB to q;
                schedule(); // CPU调度
            }
        }
        Lock::Release(){
            value = 0;
            remove one thread t from q;
            wakeup(t);
        }
        
      • Exchange

        int lock = 0; //共享数据
        // 线程Ti:
        int key;
        do{
            key = 1;
            while(key == 1) exchange(lock, key);
            critical section //临界区代码
            lock = 0;
            remainder section //其他代码
        }
        
    4. 优点

      • 适用于单处理器或共享内存的多处理器中的任意数量的进程
      • 简单且容易证明
      • 支持多临界区
    5. 缺点

      • 忙等消耗CPU资源
      • 由于锁分配的随机性,当进程离开临界区,且多个进程等待临界区时,可能导致饥饿
      • 死锁:如果一个低优先级进程进入临界区,而一个高优先级进程也有需求,高优先级进程获得处理器并等待临界区 ⇒ 可通过优先级反转解决
  • 相关阅读:
    java IO流 (八) RandomAccessFile的使用
    java IO流 (九) Path、Paths、Files的使用
    java 面向对象(三十七):反射(一) 反射的概述
    iOS下JS与OC互相调用(二)--WKWebView 拦截URL
    iOS下JS与OC互相调用(一)--UIWebView 拦截URL
    iOS下JS与原生OC互相调用(总结)
    Android简易实战教程--第十四话《模仿金山助手创建桌面Widget小部件》
    Android简易实战教程--第十三话《短信备份和还原~三》
    Android初级教程:屏幕分辨率
    Android初级教程:单击事件的传递机制初谈
  • 原文地址:https://www.cnblogs.com/DreamEagle/p/15900285.html
Copyright © 2020-2023  润新知