[转]skynet Lua中的协程
Lua中的协程
http://www.outsky.org/code/lua-coroutine.html
Sep 6, 2014
Lua中的协程和其他变量一样,都是第一类值(first-class alue),可以被保存在变量中,可以被作为参数传递,可以被函数返回。
协程有4种状态:挂起(suspended),运行(running),死亡(dead)和正常(normal)。
Lua为协程提供了3个基础接口:create,resume和yield。
#coroutine.create
- 创建一个新的协程,并为它的运行分配一个独立的栈
- 协程处于挂起状态(suspended)
- 接受一个函数作为参数,这个函数就是协程的主程序块
- 返回这个协程
- 挂起点被设置为主程序块的第一句
#coroutine.resume
- 启动一个协程(第一次启动或从暂停状态启动)
- 自身(如果是协程的话)处于正常状态,被启动的协程处于运行状态
- 第一个参数为所要启动的协程
- 协程从它的挂起点开始执行
- 一直执行到被挂起或终止
- 导致协程终止的情况有两种:它的主程序块正常返回、运行过程中出错
- 执行结束后,控制权递交给此协程被激活的地方
#coroutine.yield
- 挂起一个协程
- 协程处于挂起状态
- 协程的运行状态被记录
- 激活它的那个coroutine.resume返回
#协程间通信
- 协程第一次被启动时,传递给coroutine.resume的参数将传递给协程的主程序
- 协程挂起时,传递给coroutine.yield的参数将作为上次启动它的coroutine.resume的返回值返回
- 协程被再次启动时,传递给coroutine.resume的参数将作为上次挂起它的coroutine.yield的返回值返回
- 协程死亡时,主程序返回的值将作为上次启动它的coroutine.resume的返回值返回
#实验
##状态
local function status(str, c)
print(str, coroutine.status(c))
end
local c1,c2
c1 = coroutine.create(function()
status("<c2>", c2)
print("before c1 yield")
coroutine.yield()
print("after c1 yield")
end)
c2 = coroutine.create(function()
status("<c2>", c2)
print("before c2 resume c1")
coroutine.resume(c1)
print("after c2 resume c1")
end)
status("<c2>", c2)
coroutine.resume(c2)
status("<c1>", c1)
status("<c2>", c2)
coroutine.resume(c1)
status("<c1>", c1)
输出:
outsky@x201:~/tmp$ lua test.lua
<c2> suspended
<c2> running
before c2 resume c1
<c2> normal
before c1 yield
after c2 resume c1
<c1> suspended
<c2> dead
after c1 yield
<c1> dead
##通信
local c = coroutine.create(function(...)
print("c start:", ...)
print("c yield return:", coroutine.yield("c yield"))
return "c dead"
end)
print("main start c")
local _,r = coroutine.resume(c, "main start c")
print("main resume return:", r)
print("--------")
print("main resume c")
_,r = coroutine.resume(c, "main resume c")
print("main resume return again:", r)
输出:
outsky@x201:~/tmp$ lua test.lua
main start c
c start: main start c
main resume return: c yield
--------
main resume c
c yield return: main resume c
main resume return again: c dead
[转]skynet Lua中的协程的更多相关文章
- lua中的协程
lua中的协程和线程类似: 1. 协程拥有自己的独立的栈,局部变量,和指令: 2. 所有协程都可以共享全局变量: 3. 协程不能像线程那样并行执行,协程之间需要相互协调执行,同一个时刻只能运行一个协程 ...
- Unity中的协程(一)
这篇文章很不错的问题,推荐阅读英文原版: Introduction to Coroutines Scripting with Coroutines 这篇文章转自:http://blog.csdn. ...
- 深入tornado中的协程
tornado使用了单进程(当然也可以多进程) + 协程 + I/O多路复用的机制,解决了C10K中因为过多的线程(进程)的上下文切换 而导致的cpu资源的浪费. tornado中的I/O多路复用前面 ...
- Lua 5.3 协程简单示例
Lua 5.3 协程简单示例 来源 http://blog.csdn.net/vermilliontear/article/details/50547852 生产者->过滤器->消费者 模 ...
- python中的协程及实现
1.协程的概念: 协程是一种用户态的轻量级线程.协程拥有自己的寄存器上下文和栈. 协程调度切换时,将寄存器上下文和栈保存到其他地方,在切换回来的时候,恢复先前保存的寄存器上下文和栈. 因此,协程能保留 ...
- fasthttp中的协程池实现
fasthttp中的协程池实现 协程池可以控制并行度,复用协程.fasthttp 比 net/http 效率高很多倍的重要原因,就是利用了协程池.实现并不复杂,我们可以参考他的设计,写出高性能的应用. ...
- Golang 入门系列(六)理解Go中的协程(Goroutine)
前面讲的都是一些Go 语言的基础知识,感兴趣的朋友可以先看看之前的文章.https://www.cnblogs.com/zhangweizhong/category/1275863.html. 今天就 ...
- python中的协程:greenlet和gevent
python中的协程:greenlet和gevent 协程是一中多任务实现方式,它不需要多个进程或线程就可以实现多任务. 1.通过yield实现协程: 代码: import time def A(): ...
- xlua 实现协程替换Unity中的协程
C#中的协程: IEnumerator ShowSpiritInfo() { UIMessageMgr.ShowMsgWait(true); DestroyUIModelInfo(); bool is ...
随机推荐
- 实战dataguard主从切换
前言: 众所周知DataGuard一般的切换分成两种,一种是系统正常的情况下的切换这种方式为:switchover是无损切换,不会丢失数据:另外一种方式属于灾难情况下的切换,这种情况下一般主库已经启动 ...
- ssm的web项目,浏览器使用get方法传递中文参数时,出现乱码
ssm的web项目,浏览器使用get链接传递的为中文参数时,出现乱码 做搜索功能时,搜索手机,那么浏览器传递的参数为中文参数“手机”,但传递的默认编码格式为iso-8859-1,所以传到后台时,是乱码 ...
- ActiveMQ使用例子
网上收集的例子:有broker,producer,consumer public class MqApp { public static void main(String[] args) throws ...
- zabbix安装教程
1.下 载 https://www.zabbix.com/download 往下拉选择到源码版本下载 2.创建zabbix用户 zabbix需要以非root用户运行:如果以root用户运行那么他将会自 ...
- Windows添加用户和组命令
查看当前存在用户: net user 查看当前用户组: net localgroup 添加用户(以添加用户ls密码abcd1234为例): net user ls abcd1234 /add 添加用户 ...
- OpenJDK换为JDK(CentOS)
说明:应该来说没必要非把OpenJDK卸载掉,只要让$PATH中我们安装的jdk的目录较OpenJDK所在的/usr/bin先出现就好了:简言之跳过下边的第一步直接从第二步开始更科学一些. 1.卸载O ...
- Java Code Examples for org.codehaus.jackson.map.DeserializationConfig 配置
The following code examples are extracted from open source projects. You can click to vote up the e ...
- Scanner类完成用户键盘录入
l Scanner类 Scanner类是引用数据类型的一种,我们可以使用该类来完成用户键盘录入,获取到录入的数据. Scanner使用步骤: 导包:import java.util.Scanner; ...
- MySql多个count查询
现有一个student表结构数据如下: id hight sex age 1 160 0 16 2 170 1 16 3 180 1 17 4 160 1 16 5 170 ...
- python2x 与 python3x 区别
python2.x 与 python3.x 的区别: 1. python2.x 的源码编码不规范,源码重复较多:python3.x 的源码编码规范,清晰.优美.简单 2. python2.x的默认字符 ...