没有线性化点的方法总是不可线性化的吗?

时间:2009-09-03 20:16:13

标签: concurrency multithreading linearization

如果你可以肯定地证明方法没有线性化点,那么它是否必然意味着该方法不可线性化?另外,作为子问题,如何证明方法没有线性化点?

3 个答案:

答案 0 :(得分:2)

答案 1 :(得分:2)

为了建立上述答案,可以将方法 描述为可线性化。正如djoker提到的那本书所提到的那样:http://www.amazon.com/dp/0123705916/?tag=stackoverfl08-20

第69页的

,练习32,我们看到

enter image description here

应该注意的是,enq()确实是一种方法,被描述为可线性化/不可线性化。

证明存在可线性化的点可归结为查找是否存在可以中断线性化的示例。如果假设方法中的各种读/写内存操作是可线性化的,然后通过矛盾证明存在这种假设导致的非线性化情况,则可以声明前面提到的读/写操作是< strong>不有效的线性化点。

例如,采用以下enq()/ deq()方法,假设它们是标准队列实现的一部分,带有头/尾指针和后备数组“arr”:

public terribleQueue(){
  arr = new T[10];
  tail = 0;
  head = 0;
}

void enq(T x){
  int slot = tail;
  arr[slot] = x;
  tail = tail + 1;
}

T deq(){
  if( head == tail ) throw new EmptyQueueException();
  T temp = arr[head];
  head = head + 1;
  return temp;
}  

在这个可怕的实现中,我们可以很容易地证明,例如,enq的第一行是一个有效的线性化点,假设线性化点,然后找到另外显示的例子,如下所示:

以示例两个线程A和B以及示例历史记录为例:

A: enq( 1 )
A: slot = 0
B: enq( 2 )
B: slot = 0

(A和B现在超过了它们的线性化点,因此我们不允许对它们进行重新排序以符合我们的历史记录)

A: arr[0] = 1
B: arr[0] = 2
A: tail = 1
B: tail = 2

C: deq()
C: temp = arr[0] = 2
C: head = 1
C: return 2

现在我们看到,由于我们选择线性化点(它修正了A和B的顺序),这种执行将不可能使线性化,因为无论我们把它放在哪里,我们都不能使C的deq返回1。 / p>

有点冗长的答案,但我希望这有帮助

答案 2 :(得分:0)

这个答案是基于我第一次阅读维基百科上的线性化,并尝试将其映射到我之前通过发生在关系之前对内存一致性的理解。所以我可能误解了这个概念。

  

如果你可以肯定地证明方法没有线性化点,那么   它必然意味着该方法不可线性化?

然而,这些案件非常罕见。

  

如何证明方法没有线性化点?

正如我理解线性化点,我可能在这里错了,它们就是在线程之间建立关系之前发生的事情。如果一个方法(递归地通过它依次调用的每个方法)没有建立这样的关系,那么我会断言它没有线性化点。