async-lock模塊理解


        在Appium1.7.1里集成了一個同步模塊async-lock用來支持多會話功能。

        只能說就算是以單線程高並發聞名的I/O密集型Nodejs也不得不擴展額外的同步塊方法,或者說,在現有的計算機體系結構和配備的操作系統之下,所有的編程語言都無法摒棄同步信息塊。

        不過想想也是,這個世界原本是處於無序的狀態,只是有了人類的干預,才會讓一切事情直着走。要是沒有同步塊,所有的線程(Nodejs底層的異步也是多線程)就會如野草生成一般,力量強大,但不可被控制,而不可被控制恰恰是不能被人類所容忍的。

        首先需要明白一點的是,或者說以下內容的前提是,Nodejs碰到異步回調會啟動I/O,之后繼續往下執行。

        以官網的兩句代碼(https://www.npmjs.com/package/async-lock)為例:

        user1和user1操作redis數據庫,取同一個鍵的值乘以2:

User1
lock.acquire('key', function(cb){
    // Concurrency safe
    redis.get('key', function(err, value){
        redis.set('key', value * 2, cb);
    });
}, function(err, ret){
});
User2
lock.acquire('key', function(cb){
    // Concurrency safe
    redis.get('key', function(err, value){
        redis.set('key', value * 2, cb);
    });
}, function(err, ret){
});

acquire函數的簽名如下:

AsyncLock.prototype.acquire = function (key, fn, cb, opts)

key:就是”key”

fn:就是執行的函數

cb:fn函數執行完后的回調函數

opts:配置參數

 

再看acquire函數的具體實現

對於User1,進入acquire函數執行的是:

這里是個關鍵:queue是一個字典型,一開始key為空,queue[‘key’]已經被賦值空數組了,執行exec(true)函數。

exec函數:

if else判斷需要返回的是Promise,還是以函數回調的方式結束

User1、User2的例子是函數回調方式,所以進入if條件執行。

cb是fn(cb)傳過來的,在執行完fn()函數后,就會調用cb:

這里是重點,在調用fn之前,都是CPU在執行,現在執行fn函數,會有回調,這個時候異步I/O啟動,CPU繼續往下執行,這里的CPU往下執行不是進入fn函數體,而是執行User2的代碼,即開始執行:

 

還是進入acquire函數,這個時候走的是另一個分支:

 

把exec函數存進一個數組,然后User2就執行完了。CPU繼續往下執行User2之后的代碼。

假如在某個時刻,User1的異步執行到了cb函數,即紅框內的函數:

 

會調用done函數,其中的關鍵如下:

可以看到,User2被移出,並且執行其中的exec函數,這樣就能保證User2的異步代碼在User1之后執行。

總結起來,是以一個中間共有的隊列,存放異步函數,在上一個操作完臨界資源后,再從隊列里shift出來執行異步函數,以達到同步的目的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM