成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

lamport面包店算法簡介

zhunjiee / 1860人閱讀

摘要:序面包店算法是解決多個線程并發(fā)訪問一個共享的單用戶資源的互斥問題的算法。面包店一次只能接待一位顧客的采購。已知有位顧客要進入面包店采購,按照次序安排他們在前臺登記一個簽到號碼。顧客根據(jù)簽到號碼的由小到大的順序依次入店購貨。

Lamport面包店算法是解決多個線程并發(fā)訪問一個共享的單用戶資源的互斥問題的算法。由萊斯利·蘭波特發(fā)明。

算法類比

Lamport把這個并發(fā)控制算法非常直觀地類比為顧客去面包店采購。

面包店一次只能接待一位顧客的采購。

已知有n位顧客要進入面包店采購,按照次序安排他們在前臺登記一個簽到號碼。該簽到號碼逐次增加1。

顧客根據(jù)簽到號碼的由小到大的順序依次入店購貨。

完成購買的顧客在前臺把其簽到號碼歸0。如果完成購買的顧客要再次進店購買,就必須重新排隊。

這個類比中的顧客就相當(dāng)于線程,而入店購貨就是進入臨界區(qū)獨占訪問該共享資源。由于計算機實現(xiàn)的特點,存在兩個線程獲得相同的簽到號碼的情況,這是因為兩個線程幾乎同時申請排隊的簽到號碼,讀取已經(jīng)發(fā)出去的簽到號碼情況,這兩個線程讀到的數(shù)據(jù)是完全一樣的,然后各自在讀到的數(shù)據(jù)上找到最大值,再加1作為自己的排隊簽到號碼。

為此,該算法規(guī)定如果兩個線程的排隊簽到號碼相等,則線程id號較小的具有優(yōu)先權(quán)。

原理

Lamport時間戳原理如下:

每個事件對應(yīng)一個Lamport時間戳,初始值為0

如果事件在節(jié)點內(nèi)發(fā)生,時間戳加1

如果事件屬于發(fā)送事件,時間戳加1并在消息中帶上該時間戳

如果事件屬于接收事件,時間戳 = Max(本地時間戳,消息中的時間戳) + 1

5個原則

為了請求資源,進程A發(fā)送消息(Tm:A)給所有的其他進程,并且把這個消息放到進程隊列中,Tm是消息的時間戳

當(dāng)進程B接收到了進程A的(Tm:A)請求后,會把它放到自己的請求隊列,然后發(fā)送一個帶時間戳的確認消息給A

為了釋放資源,進程A移除所有(Tm:A)的請求消息,然后發(fā)送帶時間戳的A釋放資源請求消息給其他所有的進程

當(dāng)進程B接收到進程A釋放資源的請求,它會移除隊列中任意的(Tm:A)的資源請求

當(dāng)滿足以下兩個條件時,進程A會被分配該資源:

a)有一個(Tm:A)的請求,按照=>關(guān)系排在隊列第一位;

b)A接收到了一個時間戳大于Tm的來自所有其他進程的消息

代碼示例
private void processRevcMsg(Message m) throws InterruptedException {
        // 原理4 如果事件屬于接收事件,時間戳 = Max(本地時間戳,消息中的時間戳) + 1
        clock.update(m.getTimestamp());
        lastSendMap.put(m.getFrom(), m);
        switch (m.getMsgType()) {
            case REQUEST_RES:
                // rule 2 當(dāng)進程B接收到了進程A的(Tm:A)請求后,會把它放到自己的請求隊列,然后發(fā)送一個帶時間戳的確認消息給A
                addMessageToReqMap(m);
                Message ackMsg = new Message(pid, m.getMsgId(), MessageType.REQUEST_ACK, clock.time());
                // send ack to sender
                sendToTargetProcess(ackMsg,m.getFrom());
                break;
            case REQUEST_ACK:
                break;
            case RELEASE_RES:
                // rule 4 當(dāng)進程B接收到進程A釋放資源的請求,它會移除隊列中任意的(Tm:A)的資源請求
                dropMessageFromReqMap(m);
                break;
            default:
                break;
        }
        tryToAcquireResource();
    }

    private void tryToAcquireResource() {
        synchronized (reqMap) {
            if(!reqMap.containsKey(pid) || reqMap.get(pid).isEmpty()){
                return ;
            }

            Message myMessage = reqMap.get(pid).get(0);
            int acceptCount = 1;

            // rule 5 當(dāng)滿足以下兩個條件時,進程A會被分配該資源:a)有一個(Tm:A)的請求,按照=>關(guān)系排在隊列第一位;b)A接收到了一個時間戳大于Tm的來自所有其他進程的消息

            // condition (ii) of rule 5
            // A接收到了一個來自所有其他進程的消息,而且時間戳大于Tm
            for (Map.Entry entry : lastSendMap.entrySet()) {
                if (entry.getKey() == pid) {
                    continue;
                }
                if (isFirstEarlier(myMessage, entry.getValue())) {
                    acceptCount++;
                }else{
                    return ;
                }
            }
            if (!coordinator.hasAcceptedAll(acceptCount)){
                return;
            }

            // condition (i) of rule 5
            // 有一個Tm:A的請求,按照=>關(guān)系排在隊列第一位
            for (Map.Entry> entry : reqMap.entrySet()) {
                if (entry.getKey() != pid && !entry.getValue().isEmpty()) {
                    if (!isFirstEarlier(myMessage, entry.getValue().get(0))) {
                        return;
                    }
                }
            }

            // remove this request message
            final Message firstMsg = reqMap.get(pid).remove(0);
            workingPool.execute(new Runnable() {
                public void run() {
                    coordinator.acquire(firstMsg.getMsgId(), pid, firstMsg.getTimestamp());
                    // emulate owning resources for a long time
                    try {
                        Thread.sleep(50L);
                        // rule 3 為了釋放資源,進程A移除所有(Tm:A)的請求消息,然后發(fā)送帶時間戳的A釋放資源請求消息給其他所有的進程程
                        coordinator.release(firstMsg.getMsgId(), pid, firstMsg.getTimestamp());
                        Message releaseMsg = new Message(pid, firstMsg.getMsgId(),MessageType.RELEASE_RES, clock.time());
                        sendToOtherProcesses(releaseMsg);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            });
        }
    }
doc

Lamport面包店算法

分布式系統(tǒng)理論基礎(chǔ) - 時間、時鐘和事件順序

分布式系統(tǒng)時序基礎(chǔ)

lamport

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/70377.html

相關(guān)文章

  • 什么是拜占庭將軍問題

    摘要:在這種狀態(tài)下,拜占庭將軍們才能保證有多于支軍隊在同一時間一起發(fā)起進攻,從而贏取戰(zhàn)斗拜占庭將軍問題中并不去考慮通信兵是否會被截獲或無法傳達信息等問題,即消息傳遞的信道絕無問題。共識算法的核心就是解決拜占庭將軍問題分布式網(wǎng)絡(luò)一致性問題。 本文首發(fā)于深入淺出區(qū)塊鏈社區(qū)原文鏈接:什么是拜占庭將軍問題原文已更新,請讀者前往原文閱讀 接觸區(qū)塊鏈的同學(xué),多少都聽說過拜占庭將軍問題,經(jīng)??吹交蚵牭侥衬?..

    junnplus 評論0 收藏0
  • Python數(shù)據(jù)挖掘與機器學(xué)習(xí),快速掌握聚類算法和關(guān)聯(lián)分析

    摘要:摘要前文數(shù)據(jù)挖掘與機器學(xué)習(xí)技術(shù)入門實戰(zhàn)與大家分享了分類算法,在本文中將為大家介紹聚類算法和關(guān)聯(lián)分析問題。比如,聚類算法可以實現(xiàn)公司客戶價值自動劃分,網(wǎng)頁自動歸類等。 摘要:前文數(shù)據(jù)挖掘與機器學(xué)習(xí)技術(shù)入門實戰(zhàn)與大家分享了分類算法,在本文中將為大家介紹聚類算法和關(guān)聯(lián)分析問題。分類算法與聚類到底有何區(qū)別?聚類方法應(yīng)在怎樣的場景下使用?如何使用關(guān)聯(lián)分析算法解決個性化推薦問題?本文就為大家揭曉答...

    Anchorer 評論0 收藏0
  • Paxos共識算法詳解

    摘要:只需超過半數(shù)的節(jié)點達成一致。總結(jié)是分布式一致性問題中的重要共識算法。 在一個分布式系統(tǒng)中,由于節(jié)點故障、網(wǎng)絡(luò)延遲等各種原因,根據(jù)CAP理論,我們只能保證一致性(Consistency)、可用性(Availability)、分區(qū)容錯性(Partition Tolerance)中的兩個。 對于一致性要求高的系統(tǒng),比如銀行取款機,就會選擇犧牲可用性,故障時拒絕服務(wù)。MongoDB、Redis...

    Meils 評論0 收藏0
  • 【閱讀筆記】——時間復(fù)雜度

    摘要:時間復(fù)雜度場景一一根長寸的面包,每天吃掉一寸,那么吃完整個面包需要幾天答案自然是天可以記作場景二一根寸的面包,每天吃掉剩余的一半,吃的只剩下寸,需要多少天答案以為底,的對數(shù),簡寫成,所以為天可以記作場景三每天吃掉一個雞腿,那么吃掉整個雞腿需 時間復(fù)雜度 場景一:一根長10寸的面包,每3天吃掉一寸,那么吃完整個面包需要幾天?答案自然是:3×10=30天可以記作:T(n) = 3n 場景二...

    keithxiaoy 評論0 收藏0

發(fā)表評論

0條評論

zhunjiee

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<