繁体   English   中英

多处理器编程:无锁堆栈

[英]Multiprocessor programming: lock-free stacks

在为即将到来的并发系统考试做准备的过程中,我试图从教科书“多处理器编程的艺术”中完成一些问题。 一个问题是困扰我:

练习129:在我们的LockFreeStack对象中使用相同的共享BackOff对象进行推送和弹出是否有意义? 我们怎样才能在EliminationBackOffStack中构建空间和时间的退避?

这个问题让我感到困惑,因为我想到的第一件事就是它没有意义,因为所有退避对象都会让进程等待,所以为什么不分享呢? 问题的第二部分完全没有我,任何帮助都是最受欢迎的。

LockFreeStack的代码:

public class LockFreeStack<T> {

    AtomicReference<Node> top = new AtomicReference<Node>(null);

    static final int MIN_DELAY = ...;
    static final int MAX_DELAY = ...;
    Backoff backoff = new Backoff(MIN_DELAY, MAX_DELAY);

    protected boolean tryPush(Node node) {
        Node oldTop = top.get();
        node.next = oldTop;
        return(top.compareAndSet(oldTop, node));
    }

    public void push(T value) {
        Node node = new Node(value);
        while (true) {
            if (tryPush(node)) {
                return;
            } else {
                backoff.backoff();
            }
        }
    }

不确定我的任何ramblings是否有帮助,但无论如何我都会按“发布”按钮。

答案取决于backoff()的实现。 由于此处的目标是避免同步,因此不会有任何本地存储 - 可能是ThreadLocal某些存储。 如果退避算法使用随机数发生器,它也需要是可重入的。 所以很有可能你能够poppush之间分享它 - 现在你想要。 由于推送和弹出都试图改变top引用,如果后退给予连续线程大不相同的数字将是好的。 推或弹出更多的争论? 我们是否需要采用一种或另一种方法更积极地退缩? 如果这是一个通用堆栈,那么你就不会知道。

关于退避如何“重组”,我也不确定。 您是否可以使用成功的推送或弹出机会来减少退避时间? 如何在ThreadLocal指定的序列中随机退避等待与素数之间的差异如何?

从同步的角度来看第一个问题,我认为为推送和弹出提供相同的BackOff对象是有意义的。 无论这个类的实现如何。 这样做的原因是,如果我们有一个堆栈,我们必须在删除和添加项目到堆栈时保持一致的状态。 但是,如果我们只是偷看(查看堆栈的第一个元素或顶部),那么我们可能会有多个BackOff对象查看它,因为读取不应该锁定有问题的数据源。 第二个问题是要求为该类发布代码。

在这种情况下使用退避是过度杀戮。

任何真实世界的应用程序都应该花费更多的时间来处理节点,而不是在堆栈上下移动。 通过比较的堆栈操作应该非常短。 因此,两个线程不太可能同时访问堆栈。 但是,它有时会发生,因此您需要编写正确的代码。

public void push(T value) { 
   Node node = new Node(value); 
   while (!tryPush(node)) 
       backoff.backoff(); 
 } 

恕我直言:可以缩短为

public void push(T value) { 
   Node node = new Node(value); 
   while (!tryPush(node));
} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM