• 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出来执行异步函数,以达到同步的目的。

  • 相关阅读:
    IOC基础
    spring ioc原理
    spring ioc原理
    2014年度辛星css教程夏季版第一节
    2014年度辛星html教程夏季版第八节
    2014年度辛星html教程夏季版第七节
    2014年度辛星html教程夏季版第六节
    2014年度辛星html教程夏季版第五节
    2014年度辛星html教程夏季版第四节
    2014年度辛星html教程夏季版第三节
  • 原文地址:https://www.cnblogs.com/cool-fire/p/7766310.html
Copyright © 2020-2023  润新知