Lua 5.3 协程简单示例

Lua 5.3 协程简单示例

来源 http://blog.csdn.net/vermilliontear/article/details/50547852

 

生产者->过滤器->消费者 模式的协程示例

function receive(prod)
    local status, value = coroutine.resume(prod)
    return value
end

function send(x)
    coroutine.yield(x)
end

function producer()
    return coroutine.create(function ()
        while true do
            local x = io.read()
            send(x)
        end
    end)
end

function filter(prod)
    return coroutine.create(function ()
        local line = 1
        while true do
            local x = receive(prod)
            x = string.format("%5d %s", line, x)
            send(x)
            line = line + 1
        end
    end)
end

function consumer(prod)
    while true do
        local x = receive(prod)
        io.write(x, "\n")
    end
end


--[[ "producer()" 创建了一个"coroutine", 由filter掌控; 
      "filter()" 创建了一个"coroutine", 由consumer掌控. --]]
consumer(filter(producer()))

 

运行截图现象

 

 

 coroutine.wrap 与 coroutine.create 的区别 

-- coroutine.wrap 返回函数
co1 = coroutine.wrap(function (a)
        local c = coroutine.yield(a+1)
        print("wrap yield before a and c: ", a, c)
        return 2 * a
    end)

b = co1(20)
print(b)
d = co1(20+30)
print(d)

print("----------------")

-- coroutine.create 返回协程本身
co2 = coroutine.create(function (a)
        local c = coroutine.yield(a+1)
        print("wrap yield before a and c: ", a, c)
        return 2 * a
    end)

k, v = coroutine.resume(co2, 20)
print(k, v)
k, v = coroutine.resume(co2, 20+30)
print(k, v)

 

运行现象:

 

 

使用”coroutines”实现了简单的抢占式线程

threads = {}
time = os.clock()
limit_time = 0.111

function cal(from, to)
    local sum = 0;
    for i = from, to, 1 do
        sum = sum + i
        if(os.clock() - time) >= limit_time then
            print(string.format("Worker %d calculating, limit_time(%f), time(%f), %f%%.", 
                worker, limit_time, time, (i / to * 100)))
            time = os.clock()
            coroutine.yield()
        end
    end
end

function job(from, to)
    local co = coroutine.create(function ()
            cal(from, to)
        end)
    table.insert(threads, co)
end

job(1, 10000)
job(1000, 50000)
job(5000, 60000)
job(10000, 70000)

while true do
    local n = #threads
    if n == 0 then
        break
    end
    for i = 1, n do
        worker = i -- 全局变量
        local status = coroutine.resume(threads[i])
        if not status then
            table.remove(threads, i)
            break
        end
    end
end

 

 

运行现象:

 

posted @ 2017-10-27 02:11  lsgxeva  阅读(1818)  评论(0编辑  收藏  举报