zoukankan      html  css  js  c++  java
  • lua协程----ngx-lua线程学习笔记

       
    
    --[[
    - @desc   lua数据输出
    - @param  string   字符串 
    - return  string
    --]]
    function dump(v)
        if not __dump then
            function __dump(v, t, p)    
                local k = p or "";
    
                if type(v) ~= "table" then
                    table.insert(t, k .. " : " .. tostring(v));
                else
                    for key, value in pairs(v) do
                        __dump(value, t, k .. "[" .. key .. "]");
                    end
                end
            end
        end
    
        local t = {'======== Lib:Dump Content ========'};
        __dump(v, t);
        print(table.concat(t, "
    "));
    end
    
    --coroutine  是一个table 有一些方法 create  wrap 
    
    --create() 创建coroutine,返回coroutine, 参数是一个函数,当和resume配合使用的时候就唤醒函数调用
    
    
    --resume()   (1)第一次调用的作用是 激活coroutine,也就是让协程函数开始运行;
                 (2)第大于1次调用的作用是 唤醒yield,使挂起的协同接着上次的地方继续运行。该函数可以传入参数
                    --1. 一定要注意区分,第一次启动coroutine的时候,resume的参数传给匿名函数(以后不在进行匿名函数的形参赋值);
                    --2. 在唤醒yield的时候,参数是传递给yield()的。直接从yield()的位置往下执行
                    --3. 匿名函数执行完毕后,再次调用coroutine.resume不在起作用,因为协成状态已经停止
                    
                    
    --coroutine.yield() 挂起coroutine, 相当于是一个特殊的return语句,只是它只是暂时性的返回(挂起),并且yield可以像return一样带有返回参数,这些参数是传递给resume的。
    --coroutine.status() 查看coroutine的状态
    --注:coroutine的状态有三种:dead,suspend,running,具体什么时候有这样的状态请参考下面的程序
    
    --coroutine.wrap() 创建coroutine,返回一个函数,一旦你调用这个函数,就进入coroutine,和create功能重复
    --coroutine.running() 返回正在跑的coroutine,一个coroutine就是一个线程,当使用running的时候,就是返回一个corouting的线程号
    
    
    
    
    
    
    
    
    coroutineFunc = function (a, b) 
        for i = 1, 10 do
            ngx.say(i, a, b)
            coroutine.yield()
        end
    end
    
    co2 = coroutine.create(coroutineFunc)        --创建协同程序co2
    coroutine.resume(co2, 100, 200)                -- 1 100 200 开启协同,传入参数用于初始化
    coroutine.resume(co2)                        -- 2 100 200 
    coroutine.resume(co2, 500, 600)                -- 3 100 200 继续协同,传入参数无效
    
    co3 = coroutine.create(coroutineFunc)        --创建协同程序co3
    coroutine.resume(co3, 300, 400)                -- 1 300 400 开启协同,传入参数用于初始化
    coroutine.resume(co3)                        -- 2 300 400 
    coroutine.resume(co3)                        -- 3 300 400 
    
    
    
    co = coroutine.create(function (a, b)
                       dump(a);
                       ngx.say("co", a, b);
                       ngx.say("cooo", coroutine.yield());--第一次进来的时候这里直接停止, cooo没有输出 第二次进来在停止的地方继续执行
                       
                       ngx.say("cooooo", coroutine.yield());--第三次进来时 在停止的地方继续执行  cooooo输出
                   end)
                   
    coroutine.resume(co, 1, 2)        --co12
    ngx.say("
    ");
    coroutine.resume(co, 3, 4, 5)        --co 1 2 3 4 5,这里的两个数字参数由resume传递给yield 
    coroutine.resume(co, 7,8) 
    coroutine.resume(co, 6,9) --第四次不执行
    
    
    
    
    
    
    
    
    
    
    produceFunc = function()
        while true do
            local value = io.read()
            print("produce: ", value)
            coroutine.yield(value)        --返回生产的值
        end
    end
    
    filteFunc = function(p)
        while true do
            local status, value = coroutine.resume(p);  --执行 produceFunc函数
            value = value *100            --放大一百倍
            coroutine.yield(value)
        end
    end
    
    consumer = function(f, p)
        while true do
            local status, value = coroutine.resume(f, p);  --唤醒生产者进行生产  执行filteFunc函数并把produceFunc当做参数传入 
            print("consume: ", value)
        end
    end
    
    --消费者驱动的设计,也就是消费者需要产品时找生产者请求,生产者完成生产后提供给消费者
    producer = coroutine.create(produceFunc)
    filter = coroutine.create(filteFunc)
    consumer(filter, producer)
    
    
    
    
    
     
    
    ------ngx_lua多线程 案例------
    local t1 = ngx.now()  
    local function capture(uri, args)  
    
       return ngx.location.capture(uri, args)  --请求本地的url地址
     
      --[[ 
       local res1,res2 = ngx.location.capture_multi({ -- 一次请求多个本地url
                  {"/api1", {args = ngx.req.get_uri_args()}},  
                  {"/api2", {args = ngx.req.get_uri_args()}}  
      
            })  
      --]]
    end  
    
    local thread1 = ngx.thread.spawn(capture, "/test", {args = ngx.req.get_uri_args()})  --开启第一个线程; 第一个参数是匿名函数 后面的参数是匿名函数的参数
    local thread2 = ngx.thread.spawn(capture, "/test", {args = ngx.req.get_uri_args()})  --开启第二个线程
    local ok1, res1 = ngx.thread.wait(thread1)  --等待第一个线程的返回结果  
    local ok2, res2 = ngx.thread.wait(thread2)  --等待第二个线程的返回结果
    local t2 = ngx.now()  
    
    dump(ok1); 
    dump(res1);
    dump(t1 .. '--' .. t2);
     
    ngx.print("<br/>", res1.body, tostring(t2-t1))  
    ngx.print("<br/>", res2.body, tostring(t2-t1))  
    
    
    
     
     
     
  • 相关阅读:
    【PAT甲级】1014 Waiting in Line (30 分)(队列维护)
    【PAT甲级】1013 Battle Over Cities (25 分)(并查集,简单联通图)
    获取当前时间
    设备版本,设备号,APP版本,APP名称获取
    获取设备号
    Button的图像位置设置
    UIButton设置imgae图片自适应button的大小且不变形
    手势图片:拖拽捏合旋转放大
    Unable to add App ID because the '10' App ID limit in '7' days has been exceeded.
    iOS开发系列--触摸事件、手势识别、摇晃事件、耳机线控
  • 原文地址:https://www.cnblogs.com/sixiong/p/5920742.html
Copyright © 2011-2022 走看看