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

Concurrency 没有线性化点的方法总是不可线性化的吗?,concurrency,multithreading,linearization,Concurrency,Multithreading,Linearization,如果你可以肯定地证明一个方法没有线性化点,那么这是否一定意味着该方法是不可线性化的?另外,作为一个子问题,你如何证明一个方法没有线性化点?这个答案是基于我第一次在维基百科上阅读关于线性化的内容,并试图通过“先发生后关系”将其映射到我对内存一致性的现有理解。所以我可能误解了这个概念 如果你能肯定地证明一个方法没有线性化点,你会这样做吗 这必然意味着该方法不可线性化 在这种情况下,共享的可变状态可以由多个线程并发操作,而无需任何同步或可见性辅助,并且仍然可以维护所有不变量,而不会有损坏的风险 然而,

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

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

如果你能肯定地证明一个方法没有线性化点,你会这样做吗 这必然意味着该方法不可线性化

在这种情况下,共享的可变状态可以由多个线程并发操作,而无需任何同步或可见性辅助,并且仍然可以维护所有不变量,而不会有损坏的风险

然而,这些病例非常罕见

你如何证明一个方法没有线性化点

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

如果你能肯定地证明一个方法没有线性化点,那么它是否一定要这样做 If you can definitely prove that a method has no linearization points, does it necessarily mean that that method is not linearizable? 是否意味着该方法不可线性化? 首先,线性化不是方法的属性,而是执行序列的属性。

你如何证明一个方法没有线性化点? 这取决于执行顺序,我们是否能够找到该方法的线性化点 或者不是

例如,对于FIFO队列上的线程A,我们有以下序列。t1、t2、t3是时间 间隔时间

A.enq(1)A.enq(2)A.deq(1)
t1 t2 t3

我们可以选择前两种enq方法的线性化点(lp)分别作为时间间隔t1和t2中的任意点,以及时间间隔t3中的任意点作为deq。对于这些方法,我们选择的点是lp

现在,考虑一个错误的执行< /P> A.enq(1)A.enq(2)A.deq(2)
t1 t2 t3

Linerizability允许lp尊重实时订购。因此,方法的lp应遵循时间顺序,即t1 希望这对您有所帮助,如果您需要了解更多,可以阅读本书:

在上述答案的基础上,可以将方法描述为可线性化。正如德约克在书中提到的:

在第69页练习32中,我们看到

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

证明存在可线性化点归结为发现是否存在可破坏线性化的示例。如果您假设一个方法中的各种读/写内存操作是可线性化的,然后用矛盾的方式证明这种假设会导致一些不可线性化的情况,那么您可以声明前面提到的读/写操作不是有效的线性化点

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

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

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

A: enq( 1 )
A: slot = 0
B: enq( 2 )
B: slot = 0
(A和B现在已经过了它们的线性化点,因此我们不允许对它们重新排序以适应我们的历史)

现在我们看到,由于我们选择了线性化点(它固定了A和B的顺序),这个执行将不可能使线性化,因为我们不能使C的deq返回1,不管我们把它放在哪里


这是一个冗长的回答,但我希望这能有所帮助

谢谢!这有点帮助。。。不过,这对我来说仍然是个谜:P
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;
}  
A: enq( 1 )
A: slot = 0
B: enq( 2 )
B: slot = 0
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