lua coroutine & skynet
来源:互联网 发布:淘宝店粉丝怎么看 编辑:程序博客网 时间:2024/05/21 06:33
1.lua中的协程
thread type
用于创建协程(coroutines),跟OS的thread不是一个概念
CoroutinesPython则不同,Python的线程就是OS原生线程;不过stackless和pypy的微线程跟这个概念差不多
又名collaborative multithreading(协作多线程)
每个协程是一个独立的线程(lua thread, not os thread),当前协程只有在显式调用yield时才会挂起
coroutine.create(..)创建协程,参数:协程要执行的main函数;返回值:thread对象,指向协程
coroutine.resume(..)启动/恢复协程,第一个参数是thread对象
启动时其他参数传递给协程对应的main函数
恢复时其他参数赋值给中断时yield赋值的对象
coroutine.yield(..)挂起协程,导致coroutine.resume()立即返回,返回值:true+yield的参数;
下次resume时从这个点恢复执行
The next time you resume the same coroutine, it continues its execution from the point where it yielded, with the call to coroutine.yield returning any extra arguments passed to coroutine.resume.
coroutine.wrap(..)创建协程,参数:协程要执行的main函数;返回值:function,调用function则等效于coroutine.resume(..),参数被传递给协程main函数
跟cotoutine.resume(..)的主要区别是不捕获错误,错误会向上传播,返回值没有第一个boolean.
其实说白了就是对main函数做了一个包装,不用显示的调用resume,可以差不多像原函数一样使用
协程结束:
1.协程执行的函数终结,这种情况coroutine.resume()返回true+协程函数返回值
2.协程执行的函数出现无保护的错误,这种情况coroutine.resume()返回false+错误信息
EXAMPLE:
[dongsong@localhost skynet]$ luaLua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio> =coroutinetable: 0x113f600> for k,v in pairs(coroutine) do print(k,v) endresume function: 0x113f830yield function: 0x113f9b0status function: 0x113f8f0wrap function: 0x113f950create function: 0x113e2e0running function: 0x113f890
[dongsong@localhost lua-study]$ cat coroutine.lua function foo (a)print("foo", a)return coroutine.yield(2*a) --resume returned: true 4endco = 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) --resume returned: true 11 -9print("co-body", r, s)return b, "end" --resume returned: true 10 endend)print("main", coroutine.resume(co, 1, 10)) --main true 4print("main", coroutine.resume(co, "r")) --main true 11 -9print("main", coroutine.resume(co, "x", "y")) --main true 10 endprint("main", coroutine.resume(co, "x", "y")) --main false cannot resume dead coroutine[dongsong@localhost lua-study]$ [dongsong@localhost lua-study]$ lua coroutine.lua co-body 1 10foo 2main true 4co-body rmain true 11 -9co-body x ymain true 10 endmain false cannot resume dead coroutine
2.skynet对协程的改造过程:说白了,把lua默认的coroutine.resume和coroutine.yield作为upvalue打进了DIY的lresume和lyield,并把协程启动时间和累计运行时间作为upvalue打进lstart/lstop/lresume/lyield
int luaopen_profile(lua_State *L) { luaL_checkversion(L); luaL_Reg l[] = { { "start", lstart }, { "stop", lstop }, { "resume", lresume }, { "yield", lyield }, { NULL, NULL }, }; luaL_newlibtable(L,l); lua_newtable(L); // table thread->start time lua_newtable(L); // table thread->total time /* * table -> total time * table -> start time * table -> libtable */ lua_newtable(L); // weak table lua_pushliteral(L, "kv"); lua_setfield(L, -2, "__mode"); /* * table -> weak table * table -> total time * table -> start time * table -> libtable */ lua_pushvalue(L, -1); lua_setmetatable(L, -3); lua_setmetatable(L, -3); /* * table -> total time with weak metatable * table -> start time with weak metatable * table -> libtable */ lua_pushnil(L); luaL_setfuncs(L,l,3); /* * table -> libtable: {start=lstart, stop=lstop, resume=lresume, yield=lyield}; * upvalues of lstart/lstop/lresume/lyield: table->starttime, table->totaltime, nil */ int libtable = lua_gettop(L); //libtable = 1 lua_getglobal(L, "coroutine"); //获取lua默认的coroutine库 lua_getfield(L, -1, "resume"); //获取lua默认的coroutine.resume函数 lua_CFunction co_resume = lua_tocfunction(L, -1); //co_resume=lua默认的coroutine.resume函数 if (co_resume == NULL) return luaL_error(L, "Can't get coroutine.resume"); lua_pop(L,1); //把lua默认的coroutine.resume从stack中弹出去 /* * coroutine (lua coroutine table) * table -> libtable: {start=lstart, stop=lstop, resume=lresume, yield=lyield}; * upvalues of lstart/lstop/lresume/lyield: table->starttime, table->totaltime, nil */ lua_getfield(L, libtable, "resume"); /* * cfunction lresume * coroutine (lua coroutine table) * table -> libtable: {start=lstart, stop=lstop, resume=lresume, yield=lyield}; * upvalues of lstart/lstop/lresume/lyield: table->starttime, table->totaltime, nil */ lua_pushcfunction(L, co_resume); /* * cfunction co_resume (lua default coroutine.resume) * cfunction lresume * coroutine (lua coroutine table) * table -> libtable: {start=lstart, stop=lstop, resume=lresume, yield=lyield}; * upvalues of lstart/lstop/lresume/lyield: table->starttime, table->totaltime, nil */ lua_setupvalue(L, -2, 3); /* * cfunction lresume with upvalues: table->starttime, table->totaltime, co_resume (coroutine.resume) * coroutine (lua coroutine table) * table -> libtable: {start=lstart, stop=lstop, resume=lresume, yield=lyield}; * upvalues of lstart/lstop/lyield: table->starttime, table->totaltime, nil * upvalues of lresume: table->starttime, table->totaltime, co_resume (coroutine.resume) */ lua_pop(L,1); /* * coroutine (lua coroutine table) * table -> libtable: {start=lstart, stop=lstop, resume=lresume, yield=lyield}; * upvalues of lstart/lstop/lyield: table->starttime, table->totaltime, nil * upvalues of lresume: table->starttime, table->totaltime, co_resume (coroutine.resume) */ lua_getfield(L, -1, "yield"); lua_CFunction co_yield = lua_tocfunction(L, -1); //co_yield=coroutine.yield if (co_yield == NULL) return luaL_error(L, "Can't get coroutine.yield"); lua_pop(L,1); /* * coroutine (lua coroutine table) * table -> libtable: {start=lstart, stop=lstop, resume=lresume, yield=lyield}; * upvalues of lstart/lstop/lyield: table->starttime, table->totaltime, nil * upvalues of lresume: table->starttime, table->totaltime, co_resume (coroutine.resume) */ lua_getfield(L, libtable, "yield"); lua_pushcfunction(L, co_yield); lua_setupvalue(L, -2, 3); /* * cfunction lyield with upvalues: table->starttime, table->totaltime, co_yield (coroutine.yield) * coroutine (lua coroutine table) * table -> libtable: {start=lstart, stop=lstop, resume=lresume, yield=lyield}; * upvalues of lstart/lstop: table->starttime, table->totaltime, nil * upvalues of lresume: table->starttime, table->totaltime, co_resume (coroutine.resume) * upvalues of lyield: table->starttime, table->totaltime, co_yield (coroutine.yield) */ lua_settop(L, libtable); /* * table -> libtable: {start=lstart, stop=lstop, resume=lresume, yield=lyield}; * upvalues of lstart/lstop: table->starttime, table->totaltime, nil * upvalues of lresume: table->starttime, table->totaltime, co_resume (coroutine.resume) * upvalues of lyield: table->starttime, table->totaltime, co_yield (coroutine.yield) */ return 1; }
- lua coroutine & skynet
- skynet coroutine 运行笔记
- LUA coroutine
- 【Lua】coroutine
- lua coroutine
- lua coroutine
- coroutine 协程(skynet框架的消息处理)
- skynet lua加密方法
- skynet lua服务
- SkyNet + Lua 学习教程
- lua coroutine 参数说明
- Lua之coroutine基础
- lua中的coroutine
- lua coroutine filter
- Lua 协程 coroutine
- 关于lua coroutine
- Lua协同程序coroutine
- lua学习之coroutine
- ios--UITabBarController代理的使用
- WP_Query的使用方法
- python使用pygal进行绘制数据图表和监控图表
- reinterpre_cast用法
- 探空火箭设计感想
- lua coroutine & skynet
- Fragment使用及生命周期
- wordpress调用指定分类文章
- HTTP 协议详解1
- HDU 1754-I Hate It(线段树)
- Linux常用命令
- 调用wordpress指定分类文章2种方法
- poj 2057 树形DP+一点贪心
- BOJ 2014新生暑假个人排位赛11 整合