lua的协程

resume和yield为两个重要的函数,resume启动协程并可以传入参数,第一次传给主函数,第二次作为yield的返回值。然后协程返回数据是通过yield的参数实现的,yield的参数就是resume的返回值

co = coroutine.create(function(a)

  a = a + 1

  local rev = coroutine.yield(a)

  print(rev)

end)

print(coroutine.resume(co,1))

print(coroutine.resume(co,3))

 

调用resume和yield都会使当前协程挂起,一次只能运行一个协程

 

协程的数据传递:

coroutine_one = coroutine.create(function(a)
    io.write(a)
    a = a + 1
    local _status, _rev = coroutine.resume(coroutine_two,a)
    io.write(_rev)
    _rev = _rev + 1
    _status, _rev = coroutine.resume(coroutine_two, _rev)
    print(_rev)
    print(_status)
  end)

coroutine_two = coroutine.create(function(a)
    io.write(a)
    a = a + 1
    local _rev = coroutine.yield(a)
    io.write(_rev)
    _rev = _rev + 1
    return _rev
  end)

print("main", coroutine.resume(coroutine_one, 1))

 

 

协程的状态:

coroutine_one = coroutine.create(function(a)
    print("协程one的状态为:"..coroutine.status(coroutine_one))
    local _status, _rev = coroutine.resume(coroutine_two, a)
    print("协程two的状态为:"..coroutine.status(coroutine_two))
    print(_status, _rev)
    print(coroutine.resume(coroutine_two, _rev))
    return nil
  end)
coroutine_two = coroutine.create(function(a)
    print("协程one的状态为:"..coroutine.status(coroutine_one))
    print(a)
    print(coroutine.yield(a))
    return nil
  end)

print("协程one的状态为:"..coroutine.status(coroutine_one).." 协程two的状态为:"..coroutine.status(coroutine_two))
print("main", coroutine.resume(coroutine_one, 1))
print("协程one的状态为:"..coroutine.status(coroutine_one).." 协程two的状态为:"..coroutine.status(coroutine_two))
--dead状态的协程不能调用
--resume如果程序出错了,会返回false和错误信息
print(coroutine.resume(coroutine_one))

 

 

以下内容来自:http://www.cnblogs.com/iRidescent-ZONE/p/5640917.html    感谢原作者

协程的复杂应用:

1.生产者和消费者

以消费者为驱动,即主循环在消费者,这里有两个消费者,同时向一个生产者获取数据。生产者每产生一个数据就会被挂起,直到下次被消费者激活。

local producer = coroutine.create(function()
    local i = 0;
    
    while true do
      i = i + 1
      
      coroutine.yield(i)
    end
  end)

function comsumer_func()
  local status = 0 
  --如果data是local的话会输出comsumer1: 11
  data = 0
  while true do
    if (data >= 10) then
      break
    end
    
    status, data = coroutine.resume(producer)
    print("comsumer1:", data)
    
    coroutine.yield()
  end
end

--连个协程虽然是使用相同的函数,但是他们是独立的
local comsumer1 = coroutine.create(comsumer_func)
local comsumer2 = coroutine.create(comsumer_func)
local comsumers = coroutine.create(function(...)
    local threads = {...}
    local threads_status = {}
    for i, v in ipairs(threads) do
      threads_status[i] = true
    end
    
    while true do
      local status = false
      
      for i, v in ipairs(threads) do
        if (threads_status[i]) then
          threads_status[i] = coroutine.resume(threads[i])
        end
        
        --这句的意思是,如果status为nil或false,则status为threads_status[i],否则为status
        status = status or threads_status[i]
      end
      
      if (not status) then
        break
      end
    end
  end)

print(coroutine.resume(comsumers, comsumer1, comsumer2))

print(coroutine.status(producer))
print(coroutine.status(comsumer1))
print(coroutine.status(comsumer2))
print(coroutine.status(comsumers))

 

posted @ 2017-06-15 16:28  小张学代码  阅读(629)  评论(0编辑  收藏  举报