【问题标题】:Filter lock mutual exclusion property过滤锁互斥属性
【发布时间】:2013-08-07 17:56:15
【问题描述】:

以下是 Peterson 的 2 线程锁定算法的通用版本,允许“n”个线程/进程竞争临界区。

基本上有“n”个级别和“n”个线程。处于非活动状态或在非临界区区域中执行的线程处于级别 0。级别 n-1 是临界区。每个线程/进程在进入临界区之前必须跨越 n-1 级。

有 2 个数组,级别 [n] 和受害者 [n]。第一个数组由线程的threadId索引,entry level[i]存储threadId为'i'的线程的当前级别。第二个数组以级别编号为索引,条目victim[i] 存储最近进入级别'i'的线程的threadId。

level[]的所有元素都初始化为0。没有针对victim[]的具体初始化。

1    void lock()
2    {  int me = ThreadID.get();
3       for (int i = 1; i < n; i++)
4       { level[me] = i;
5         victim[i] = me;
6         while ((∃k != me) (level[k] >= i && victim[i] == me)) ;
7       }
8    }
9   
10   void unlock()
11   {  int me = ThreadID.get();
12      level[me] = 0;
13   }

代码直接摘自 Maurice Herlihy 和 Nir ​​Shavit 所著的《多处理器编程的艺术》一书。

问题是代码似乎不满足互斥属性!!

推理:- 第 6 行暗示,一个线程将在一个级别保持循环,直到有一些线程处于相同或更高级别,并且线程本身是进入它当前所在级别的最新线程。此外,只有一个线程可以保持在一个级别。如果第二个线程到达同一级别,那么第一个线程的“victim[i] == me”表达式将变为假,因此将被推到下一个级别。

现在,如果每个级别都有一个线程,并且级别 0 的线程尝试前进到级别 1。这会将级别 1 的线程推到级别 2,因为它不再是级别 1 的受害者。因此会有连锁反应,每个线程都会被下推一级,导致第n-2级的线程也进入临界区!!

那么代码实际上是错误的还是我解释错了什么?

【问题讨论】:

    标签: synchronization locking mutual-exclusion


    【解决方案1】:

    n 是线程数,n 是级别数 级别从0开始,n-1级别是关键部分

    如果所有级别都被一个线程填充,则不会有任何其他线程进入级别 0,即第一级。所以它永远不会发生。

    例如,如果线程数和级别数为 3。 一开始所有线程都在级别0,两个可以前进到下一个级别,一个必须根据条件等待 while ((∃k != me) (level[k] >= i &&victim[i] == me)) ; 并且从这两个线程中的一个进入关键部分的级别 2。

    现在每个级别都填充了一个线程,唯一可能的情况是临界区中的线程调用 unlock() 通过使其级别 =0 然后只有其他线程可以继续。

    重点是线程数等于层数

    【讨论】:

    • 级别 0 的线程,比如 X,不等待任何人解锁()。 for 循环以 i = 1 开始。X 可以直接将victim[1] 设置为自己的 id。事实上,如果没有。线程数 = 没有。的级别,则违反了临界区问题。如果一个线程在 CS 中,那么 n-1 个线程必须能够在 while 循环中等待。由于级别 0 不提供等待,因此级别 n-1 必须是等待级别而不是 CS。一个额外的级别 n 必须是 CS。代码也是这样说的。对于 i = n-1,所有线程都会检查 while 循环。我确信这是书中的一个错字,上面写着“n-1 级是关键部分”。
    猜你喜欢
    • 2018-05-23
    • 1970-01-01
    • 2010-09-16
    • 2010-12-17
    • 2012-06-05
    • 2015-07-20
    • 1970-01-01
    • 1970-01-01
    • 2015-10-26
    相关资源
    最近更新 更多