簡體   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