博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
lua协程
阅读量:5734 次
发布时间:2019-06-18

本文共 2421 字,大约阅读时间需要 8 分钟。

hot3.png

    协同程序与线程差不多,也就是一条执行序列,拥有自己独立的栈、局部变量和指令指针,同时又跟其他协同程序共享全局变量和其他大部分东西。从概念上来讲,线程与协同程序的主要区别在于:一个具有多线程的程序可以同时运行几个线程,而协同程序却需要彼此协作的运行。就是说,一个具有多个协同程序的程序在任意时刻只能运行一个协同程序,并且正在运行的协同程序只会在其显示的要求挂起时,它的执行才会暂停。

    lua将所有关于协同程序的函数放置在一个名为“coroutine”的table中,函数create用于创建新的血统程序,它只有一个参数,就是一个函数。该函数的代码就是协同程序需要执行的内容。create会返回一个thread类型的值,用于表示新的协同程序,一般create的参数是一个匿名函数,如:

local co = coroutine.create(function()    print("hi)end)

    一个协同程序有四种不同的状态:挂起(suspended)、运行(running)、死亡(dead)和正常(normal)。当新创建一个协同程序时,它处于挂起状态,也就是说,协同程序不会在创建它的时候自动运行。我们可以通过函数status来检查协同程序的状态。

local co = coroutine.create(function()    print("hi")end)print(coroutine.status(co))    --suspended

    函数coroutine.resume用于启动或再次启动一个协同程序的执行,并将其状态由挂起改为运行。

local co = coroutine.create(function()    print("hi")end)print(coroutine.status(co))    --suspendedcoroutine.resume(co)    --hi

    上面的代码中调用来resume函数,将协同程序co由suspended改为running状态,当打印了hi之后,co就处于死亡状态了。

    我们现在来看一下协程函数的yield,该函数可以让一个运行中的协同程序挂起,而之后可以再恢复它的运行。看下面的例子:

local co = coroutine.create(function()	for i=1,5 do 		print(i)		coroutine.yield()	endend)print(coroutine.status(co))coroutine.resume(co)print(coroutine.status(co))coroutine.resume(co)print(coroutine.status(co))coroutine.resume(co)coroutine.resume(co)coroutine.resume(co)--coroutine.resume(co)注意这句话print(coroutine.status(co))coroutine.resume(co)

   输出:

suspended1suspended2suspended345suspended    --当把上面的注释打开,这是输出为:dead

    在最后一次调用resume时,协同程序的内容已经执行完毕,并已经返回。因此,这时协同程序处于死亡状态。当在协同程序的执行中发生任何错误,Lua是不会显示错误消息的,而是将执行权返回给resume调用。当coroutine.resume的第一个返回值为false时,就表明协同程序在运行过程中发生了错误;当值为true时,则表明协同程序运行正常。

    当一个协同程序A唤醒另一个协同程序B时,协同程序A就处于一个特殊状态,既不是挂起状态(无法继续A的执行),也不是运行状态(是B在运行)。所以将这时的状态称为“正常”状态。

    Lua的协同程序还具有一项有用的机制,就是可以通过一对resume-yield来交换数据。在第一次调用resume时,并没有对应的yield在等待它,因此所有传递给resume的额外参数都视为协同程序主函数的参数。

    当协同程序中没有yield时,第一次调用resume,所有传递给resume的额外参数都将视为协同程序主函数的参数,如以下代码:

local co = coroutine.create(function (a, b, c)     print("co", a, b, c)end)coroutine.resume(co, 1, 2, 3)     -- co 1 2 3

    在resume调用返回的内容中,第一个值为 true则表示没有错误,而后面所有的值都是对影yield传入的参数:

local co = coroutine.create(function(a,b)	coroutine.yield(a+b,a-b)end)print(coroutine.resume(co,20,10))

    输出:

true	30	10

    于此对应的时,yield返回的额外值就是对应resume传入的参数:

local co = coroutine.create(function()	print(coroutine.yield())end)coroutine.resume(co)coroutine.resume(co,4,5)

    输出:

4	5

    最后,当一个协同程序结束时,它的主函数所返回的值都将作为对应resume的返回值:

local co = coroutine.create(function()	return 6,7end)print(coroutine.resume(co))

    输出:

true	6    7

转载于:https://my.oschina.net/u/815187/blog/485109

你可能感兴趣的文章
《网站情感化设计与内容策略》一1.6 情感和记忆
查看>>
pandas 的Series 里经常会出现DatetimeIndex这个类
查看>>
SQL SERVER 2012 只能识别20个CPU的问题
查看>>
【单调队列】【P1776】宝物筛选
查看>>
使用shell脚本生成数据库markdown文档
查看>>
centos和pycharm中取绝对路径的差别
查看>>
ext2磁盘布局
查看>>
MySql数据库2【常用命令行】
查看>>
动态规划---->货郎担问题
查看>>
添加虚拟子网
查看>>
Ubuntu 12.04 root用户登录设置
查看>>
存储过程点滴
查看>>
Maven编译跳过test的设置
查看>>
SQLyog图形化l数据库的操作和学习
查看>>
raspbian 怎么才能有声音?
查看>>
[LeetCode]22.Generate Parentheses
查看>>
WEB前端 CSS选择器
查看>>
计算A/B Test需要的样本量
查看>>
二叉树前序中序后序遍历的非递归方法
查看>>
mysql 行转列列转行
查看>>