lua编写的协程例子:yield的参数由resume返回了,resume的参数由yield返回。。
function foo (a) print("foo", a) return coroutine.yield(2*a) end co = coroutine.create(function (a,b) print("co-body", a, b) local r = foo(a+1) print("co-body", r) local r, s = coroutine.yield(a+b, a-b) print("co-body", r, s) return b, "end" end) print("main", coroutine.resume(co, 1, 10)) print("main", coroutine.resume(co, "r")) print("main", coroutine.resume(co, "x", "y")) print("main", coroutine.resume(co, "x", "y"))输出结果:
co-body 1 10 foo 2 main true 4 co-body r main true 11 -9 co-body x y main true 10 end main false cannot resume dead coroutine第二个例子
coro = {} coro.main = function() end coro.current = coro.main function coro.create(f) return coroutine.wrap(function(val) return nil,f(val) end) end function coro.transfer(k,val) if coro.current ~= coro.main then return coroutine.yield(k,val) else while k do coro.current = k if k == coro.main then return val end k,val = k(val) end error("coroutine ended without transfering control...") end end function foo1(n) print("1: foo1 received value "..n) n = coro.transfer(foo2,n + 10) print("2: foo1 received value "..n) n = coro.transfer(coro.main,n + 10) print("3: foo1 received value "..n) coro.transfer(coro.main,n + 10) end function foo2(n) print("1: foo2 received value "..n) n = coro.transfer(coro.main,n + 10) print("2: foo2 received value "..n) coro.transfer(foo1,n + 10) end function main() foo1 = coro.create(foo1) foo2 = coro.create(foo2) local n = coro.transfer(foo1,0) print("1: main received value "..n) n = coro.transfer(foo2,n + 10) print("2: main received value "..n) n = coro.transfer(foo1,n + 10) print("3: main received value "..n) end coro.main = main coro.current = coro.main coro.main()关于coroutine.wrap,帮助文档中有下面一段话:
Like coroutine.create, the coroutine.wrap function also creates a coroutine, but instead of returning the coroutine itself, it returns a function that, when called, resumes the coroutine. Any arguments passed to this function go as extra arguments to coroutine.resume. coroutine.wrap returns all the values returned by coroutine.resume, except the first one (the boolean error code). Unlike coroutine.resume, coroutine.wrap does not catch errors; any error is propagated to the caller.
附上运行结果:
1: foo1 received value 0 1: foo2 received value 10 1: main received value 20 2: foo2 received value 30 2: foo1 received value 40 2: main received value 50 3: foo1 received value 60 3: main received value 70