网站素材模板旅游,大都会app约,wordpress 侧栏主题,二手网站建设模块lua也有协程这个机制#xff0c;用以完成非抢占式的多任务处理。
协程与线程
协程和线程类似#xff0c;有自己的堆栈、局部变量、指令指针等等。但同时也有不一致的地方#xff0c;其中最重要的地方在于多线程程序可以同一时间运行多个线程#xff0c;而协程同一时间只能…lua也有协程这个机制用以完成非抢占式的多任务处理。
协程与线程
协程和线程类似有自己的堆栈、局部变量、指令指针等等。但同时也有不一致的地方其中最重要的地方在于多线程程序可以同一时间运行多个线程而协程同一时间只能运行一个并且运行期间只有被显式要求挂起的时候才会选择挂起操作。
基础操作
coroutine.create(func)代表创建一个协程也是个高级函数参数即是function。
coroutine.status(co)查看当前协程状态参数是协程本身返回status string。
coroutine.resume(co)使协程由挂起态转为运行态参数是协程本身以及协程需要的参数。返回的是是否成功运行如若不成功还会附加错误信息作为返回。
coroutine.yield()将当前协程挂起。
---param f async fun(...):...
---return thread
---nodiscard
function coroutine.create(f) end---param co thread
---return
---| running # 正在运行。
---| suspended # 挂起或是还没有开始运行。
---| normal # 是活动的但并不在运行。
---| dead # 运行完主体函数或因错误停止。
---nodiscard
function coroutine.status(co) end---param co thread
---param val1? any
---return boolean success
---return any ...
function coroutine.resume(co, val1, ...) end---async
---return any ...
function coroutine.yield(...) end
如下一段示例代码
co coroutine.create(function ()for i 1,3 doprint(co, i)coroutine.yield()end
end)
print(coroutine.status(co))--suspended
coroutine.resume(co)--co 1
print(coroutine.status(co))--suspended
coroutine.resume(co)--co 2
coroutine.resume(co)--co 3
print(coroutine.status(co))--suspended
coroutine.resume(co)--
print(coroutine.status(co))--dead
print(coroutine.resume(co))--false cannot resume dead coroutine
生产者-消费者
解决生产者消费者的问题就是如何能根据消费者请求数目的多少来决定生产者生产多少此刻用协程再合适不过比如官方文档的示例代码
function receive () local status, value coroutine.resume(producer) return value
end
function send (x) coroutine.yield(x)
end
producer coroutine.create( function () while true dolocal x io.read() -- produce new value send(x) end
end)
协程参数
当然我们可以试着修改这部分代码改为传入一个数组每次从中取出相应值
function receive(tb)local status, value coroutine.resume(producer,tb)return value
end
producer coroutine.create(function (tb)for i 1,#tb docoroutine.yield(tb[i])end
end)print(receive({1,2,3})) --1
print(receive({2,3,4})) --2
print(receive({5,6,7,8,9})) --3
print(receive({1,2,3,4})) --nil
发现了一个问题没有只有第一次的数组赋值是正确的之后的任意一次传参都是失败的。说明在第一次resume时就需要保证参数是正确的而且后几次传参也只能在第一次传参的基础上继续执行之后的参数并不能覆盖之前的参数。
如果这个tb是个全局变量则是
function receive()local status, value coroutine.resume(producer)return value
endproducer coroutine.create(function ()for i 1,#tb docoroutine.yield(tb[i])end
end)tb {1,2,3}
print(receive()) --1
tb {2,3,4}
print(receive()) --3
tb {4,5}
print(receive({5,6,7,8,9})) --nil
tb {4,5,6,7}
print(receive({1,2,3,4})) --nil