【发布时间】: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