美文网首页
多处理器编程的艺术 第二章 互斥 (上)

多处理器编程的艺术 第二章 互斥 (上)

作者: TheSoundOf_abb8 | 来源:发表于2017-05-11 16:21 被阅读0次

    2.1 时间

    - 线程是个状态机,其状态的转换称为事件。

    - 事件是瞬间发生的,我们假设不同的事件在不同的时间点发生。

    - 事件间隔有重叠时,称为 并发的。

    2.2 临界区

    - 某个时刻仅能够被一个线程执行的代码,称为临界区。

    - 上面的特性,称为 互斥。

    -

    +  互斥:不同线程的临界区之间没有重叠。

    + 无死锁:如果一个线程正在尝试获得一个锁,那个总会成功的获得这个锁。

    + 无饥饿:每个试图获得锁的线程最终都能成功。//无饥饿意味着无死锁。

    //无饥饿特性不保证线程在进入临界区以前需要等待多长时间。

    - 即使程序所使用的每个锁都满足无死锁特性,该程序也可能死锁。

    2.3 双线程解决方案

    2.3.1 LockOne算法

    LockOne算法的缺陷:**LockOne算法在交叉执行的时候会出现死锁。若事件writeA(flag[A] = true)与writeB(flag[B] = true)在事件readA(flag[B]==flase)和readB(flag[A]==false)之前发生,那么两个线程都将陷入无穷等待。

    2.3.2 LockTwo算法

    LockTwo类存在的缺陷:当一个线程完全先于另一个线程执行的时候就会出现死锁。但是两个线程并发地执行,却是成功的。由此,我们看到LockOne与LockTwo算法彼此互补,于是将两者结合的算法Peterson算法实现了。

    2.3.3 Peterson锁

    Peterson锁算法://双线程互斥算法

    class Peterson implements Lock {

    // thread-local index, 0 or 1

    private volatile boolean[] flag = new boolean[2];

    private volatile int victim;

    public void lock() {

    int me = ThreadID.get();

    int he = 1 - me;

    flag[me] = true;            // I’m interested

    victim = me;                // you go first

    while (flag[he] && victim == me) {}; // wait

    }

    public void unlock() {

    int me = ThreadID.get();

    flag[me] = false;           // I’m not interested

    }

    }

    -  Peterson锁是满足互斥特性,是无饥饿,无死锁的。

    2.4 过滤锁(分层策略)

    算法代码:

    class Filter implements Lock {

    int[] level;

    int[] victim;

    public Filter(int n) {

    level = new int[n];

    victim = new int[n]; // use 1..n-1

    for (int i = 0; i < n; i++) {

    level[i] = 0; //[1]

    }

    }

    public void lock() {

    int me = ThreadID.get();

    for (int i = 1; i < n; i++) { //attempt level 1 //[2]

    level[me] = i;

    victim[i] = me;

    // spin while conflicts exist

    while ((∃k != me) (level[k] >= i && victim[i] == me)) {}; //[3]

    }

    }

    public void unlock() {

    int me = ThreadID.get();

    level[me] = 0;

    }

    }

    说明:  - n 元整数组level [], level[A]的值表示线程A正在尝试进入的层。

    - 每个层都有一个victim[l] 域, 用来选出线程,“留守”本层。

    相关文章

      网友评论

          本文标题: 多处理器编程的艺术 第二章 互斥 (上)

          本文链接:https://www.haomeiwen.com/subject/towktxtx.html