博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Lua(十五)——协同程序
阅读量:1984 次
发布时间:2019-04-27

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

一:协程与线程的区别

在 Lua 里,最主要的线程是协同程序(coroutine),它跟线程差不多,拥有自己独立的栈、局部变量和指令指针,可以跟其他协同程序共享全局变量和其他大部分东西

线程跟协程的区别:线程可以同时多个运行,而协程任意时刻只能运行一个,并且处于运行状态的协程只有被挂起(suspend)时才会暂停


二:什么是协程

协程和线程都是针对于函数来说的,一个函数的正常执行步骤是执行完此函数的所有代码再继续执行下面的代码

但是协程可以让函数在某一步暂停(暂停也称为挂起),在挂起的地方先暂停函数去执行函数外的代码,然后在需要的时候让没有执行的代码继续执行


三:定义协程

——coroutine.create() 

返回值为一个协程(函数)

 

——coroutine.wrap() 
返回值为一个协程(函数)

注意:

1.create后面必须跟上括号,括号不能放在下一行
2.协程必须定义为一个匿名函数


四:开启协程

——coroutine.resume()

 

——像调用函数一样

使用coroutine.create和coroutine.wrap定义的区别:

使用create定义的协同程序在开启时需要使用coroutine.resume开启,而用wrap定义的协同程序在开启时只需要像调用函数一样开启


五:暂停协程

coroutine.yield()

使程序暂停在coroutine.yield()的地方


六:继续协程

继续协程的函数与开启协程的函数一样:

第一次执行时必须传入需要的参数,继续执行可以不传入参数,直接开启协程即可


七:协同函数的返回值

——协同函数执行完成后有返回值 

匿名函数最终返回的值就是返回的参数,可以返回多个值
1.coroutine.resume的第一个返回值永远为是否开启协程成功,后面的值才是协同函数的返回值
2.像调用函数一样开启的返回值就是协同函数的返回值

 

——协同函数暂停时有返回值 
coroutine.yield的参数就是暂停时返回的参数,可以返回多个值
1.coroutine.resume的第一个返回值永远为是否开启协程成功,后面的值才是协同函数的返回值
2.像调用函数一样开启的返回值就是协同函数的返回值


八:查看协程的状态

coroutine.status()

只能用于coroutine.create创建的协同函数,返回一个当前状态的字符串
创建一个协程后它的默认状态就是suspended

在协同函数外面获取到的状态永远都不会是running只可能是dead或者suspended,因为当协程被挂起时或者执行完时才会执行协同函数外的代码

     
想要取得正在运行的状态需要在协同函数内部获取

一个协同函数的生命周期:


九:获取正在运行的线程号

coroutine.running()

返回值为协同函数的线程号(内存地址)
同样适用于coroutine.create和coroutine.wrap定义的协程

与获取协程状态一样如果在协同函数外面获取则永远都是nil

想要取得正在运行的线程号需要在协同函数内部获取


十:案例分析

——第一个

function yieldReturn(arg) return arg endco_yieldtest = coroutine.create(    function()        print("启动协程状态"..coroutine.status(co_yieldtest))        print("--")        coroutine.yield()        coroutine.yield(1)        coroutine.yield(print("第3次调用"))        coroutine.yield(yieldReturn("第4次调用"))        return 2    end)    print("启动前协程状态"..coroutine.status(co_yieldtest))    print("--")for i = 1,6 do    print("第"..i.."次调用协程:", coroutine.resume(co_yieldtest))    print("当前协程状态"..coroutine.status(co_yieldtest))    print("--")end

 

 

 

——第二个

function foo (a)    print("foo 函数输出", a)    return coroutine.yield(2 * a) end co = coroutine.create(function (a , b)    print("第一次协同程序执行输出", a, b)    local r = foo(a + 1)         print("第二次协同程序执行输出", r)    local r, s = coroutine.yield(a + b, a - b)         print("第三次协同程序执行输出", r, s)    return b, "结束协同程序"           end)        print("main", coroutine.resume(co, 1, 10))print("--分割线----")print("main", coroutine.resume(co, "r"))print("---分割线---")print("main", coroutine.resume(co, "x", "y"))print("---分割线---")print("main", coroutine.resume(co, "x", "y"))print("---分割线---")

 

 

 

——第三个

local newProductorfunction productor()     local i = 0     while true do          i = i + 1          send(i)     -- 将生产的物品发送给消费者     endendfunction consumer()     while true do          local i = receive()     -- 从生产者那里得到物品          print(i)     endendfunction receive()     local status, value = coroutine.resume(newProductor)     return valueendfunction send(x)     coroutine.yield(x)     -- x表示需要发送的值,值返回以后,就挂起该协同程序end-- 启动程序newProductor = coroutine.create(productor)consumer()

转载地址:http://styvf.baihongyu.com/

你可能感兴趣的文章
软件质量的8个特性
查看>>
应届渣渣前端的艰难求职之路
查看>>
2021年不可错过的17种JS优化技巧(一)
查看>>
月薪15~20k的前端面试问什么?
查看>>
在 Vue 中用 Axios 异步请求API
查看>>
MySQL进阶查询(SELECT 语句高级用法)
查看>>
Mysql 之主从复制
查看>>
【工具使用】新版CSDN-markdown编辑器使用指南
查看>>
【NLP学习笔记】中文分词(Word Segmentation,WS)
查看>>
【超越白皮书7】你需要知道关于ETH2.0的几个事实
查看>>
对于时间复杂度的通俗理解
查看>>
如何输入多组数据并输出每组数据的和?
查看>>
行阶梯型矩阵
查看>>
图像处理学习笔记
查看>>
用MATLAB实现m序列的生成(MATLAB 2021a适用)
查看>>
MATLAB函数备忘(定期更新)
查看>>
13行MATLAB代码实现网络爬虫 爬取NASA画廊星图
查看>>
MATLAB指定路径保存图片方法
查看>>
Python一键获取微信推送封面图
查看>>
油猴脚本:微信推送浏览功能拓展
查看>>