【问题标题】:Consensus number of FIFO queueFIFO队列的共识数
【发布时间】:2014-12-04 20:59:01
【问题描述】:

多出队队列的确切共识数是多少?

我知道它至少是 2 个
queue.enq(1)
queue.enq(0)
线程 A 和 B 分别调用 queue.deq().
得到 1 的线程将返回它自己的值。
得到 0 的线程将返回另一个的值。

但我如何证明它正好是 2
我认为我应该只使用 2-consensus 对象来实现一个队列,但我没有设法做到。

【问题讨论】:

  • Maurice Herlihy 的论文《Wait-free synchronization》有一个证明。

标签: multithreading concurrency queue consensus


【解决方案1】:

假设它可以解决 3 个线程的共识。 考虑所有可能的线性化并发执行树中的临界状态。 向左走,你会决定 1。向右,你会决定 0。

假设线程 A deq() 来自队列,然后 B deq() 来自队列。现在我们选择了左边的分支。 然后假设线程 B deq() 来自队列,然后 A deq() 来自队列。现在我们选择了正确的分支。

现在如果线程 C 的 deq() 来自队列,它不应该关心其他 deq() 中的哪个先。无论哪种方式,队列看起来都相同。

矛盾:线程 C 将决定 2 个不同的事情,即使就其而言执行是相同的。

【讨论】:

    【解决方案2】:

    我认为Adar Hefer's 的答案是正确的。我仍然认为,个人观点,这些正式的答案很痛苦。

    作为非正式回答。如果您必须使用 FIFO 队列就多个线程达成共识,您会怎么做?所以你可以在这里存储三个或更多的提议,没问题。比你可以画的稻草,无论是赢,输,还是第二个输。仍然没有问题。但是你如何获得正确的“投票”价值?对于 WIN,您可以只获取您的 threadID,但您如何确保其他两个线程也获取获胜者的值?如果您是失败的线程,从您的角度来看,您无法看到其他两个线程中的哪一个获胜。你所知道的是你已经输了,应该采取其他建议的价值。赌一把,你可能会画出正确的——你可能不会。

    【讨论】:

    • 为什么获胜者线程不能将其 ID 或获胜值写入共享变量,然后每个人都从那里读取?
    • 嗯,是的,完全有可能。但是,它不仅仅是一个 FIFO 队列。问题将是,如何原子地解决这个问题。放置一个互斥锁(?),因为在绘制之后您确实需要存储您的号码,但是如果线程停止怎么办?看看这是怎么回事?所以一个FIFO队列的共识数是2。
    • 好吧,在 2 个线程中,您也使用建议的 [] 数组来存储值,因此“它也不仅仅是一个队列”。但我认为要计算一个对象的共识数,您可以获取该对象的任意数量的实例以及任意数量的原子 RW 寄存器,这样就可以了。然后才是真正的答案。我认为不需要互斥锁。只是共享变量可以被初始化为一个值,如果其他线程看到,他们知道它还没有被获胜者更新,他们可以继续旋转它。 (继续下一条评论)
    • 我看到的唯一真正的问题是,如果获胜者线程在挑选 WIN 稻草之后但在更新共享变量之前死亡。
    • 但这让我感到奇怪。如果是 2 个线程。如果一个线程选择了 LOSE,而第二个线程在将自己的值写入提议的 [] 数组之前就死了会发生什么?
    猜你喜欢
    • 2015-12-18
    • 2023-04-03
    • 2017-04-12
    • 2019-04-11
    • 1970-01-01
    • 1970-01-01
    • 2012-06-12
    • 1970-01-01
    • 2019-11-02
    相关资源
    最近更新 更多