Lua协程介绍

Lua协程

协程

什么是协程

协程(coroutine)是一种程序组件,它允许执行代码在不同的点暂停和恢复,从而实现协作式的多任务处理。与传统的线程不同,协程不是由操作系统调度的,而是由程序自身控制的。因此,协程提供了一种轻量级的并发机制,适用于需要多任务但不需要真正并行的场景

协程的特点

1.轻量级:协程不需要占用如线程堆栈等额外的系统资源,因此创建和切换协程的开销非常低。

2.非抢占式:协程的切换是显式的,即只有当协程主动让出控制权时,程序才会切换到另一个协程。

3.合作式多任务:多个协程之间通过显式的让出和恢复控制权来进行合作,从而实现多任务处理。

4.独立的执行上下文:每个协程都有自己的执行上下文,包括局部变量等。

协程和线程的区别

1.调度方式:线程由操作系统调度,而协程由程序自身调度。

2.并行与并发:线程可以真正并行执行(多核 CPU),而协程在任何时刻只能有一个在运行(单线程)。

3.创建和切换开销:线程的创建和上下文切换开销较大,而协程的创建和切换开销较小。

协程的工作原理

协程的核心机制是允许代码在某个点暂停(挂起),并在需要时从暂停的地方继续执行。这通常通过以下两种操作来实现:

挂起(yield):暂停协程的执行,并返回控制权给调度者(通常是调用协程的函数)。

恢复(resume):从挂起点继续执行协程。

Lua协程示例

创建协程:使用 coroutine.create 创建一个新的协程。

启动协程:使用 coroutine.resume 启动或恢复一个协程。

挂起协程:使用 coroutine.yield 挂起当前协程,并将控制权交回给调用者。

状态查询:使用 coroutine.status 查询协程的状态,状态可以是 suspended(挂起)、running(运行中)、normal(正常)或 dead(结束)。

主协程:每个 Lua 程序都有一个主协程,可以通过 coroutine.running 获取当前正在运行的协程。

lua 复制代码
-- 模拟一个简易的异步任务示例
function longRunningTask()
    local value = 0
    for i = 1, 3 do
        value = value + 1
        print("Running step", i, "with value", value)
        coroutine.yield(value)
    end
    return value
end

-- 创建协程
local co = coroutine.create(longRunningTask)

--[[
coroutine.resume 返回两个值:

布尔值,表示协程是否成功执行。true 表示协程成功执行,false 表示遇到了错误。
其他返回值,它们依赖于协程内部的执行情况:
如果协程在 coroutine.yield 处暂停,该处的返回值会作为 resume 的第二个返回值。
如果协程正常结束,coroutine.resume 的第二个返回值是协程结束时coroutine.yield(*)传入的返回值。
如果协程遇到运行错误,coroutine.resume 的第二个返回值是错误消息。

--]]

-- 恢复协程,接收每次 yield 返回的值
local status, result = coroutine.resume(co)  -- 输出 "Running step 1 with value 1"
local r = coroutine.status(co)
print("Received from yield:", status,result,r)
-- can todo something... 处理其他任务,等待下一次启动协程
status, result = coroutine.resume(co)  -- 输出 "Running step 2 with value 2"
r = coroutine.status(co)
print("Received from yield:", status,result,r)
-- can todo something...
status, result = coroutine.resume(co)  -- 输出 "Running step 3 with value 3"
r = coroutine.status(co)
print("Received from yield:", status,result,r)
-- can todo something...
status, result = coroutine.resume(co)  -- 协程完成,返回最终结果
r = coroutine.status(co)
print("Final result:", status,result,r)
相关推荐
2202_754421544 分钟前
生成MPSOC以及ZYNQ的启动文件BOOT.BIN的小软件
java·linux·开发语言
蓝染-惣右介7 分钟前
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
java·数据库·tomcat·mybatis
小林想被监督学习8 分钟前
idea怎么打开两个窗口,运行两个项目
java·ide·intellij-idea
HoneyMoose10 分钟前
IDEA 2024.3 版本更新主要功能介绍
java·ide·intellij-idea
我只会发热11 分钟前
Java SE 与 Java EE:基础与进阶的探索之旅
java·开发语言·java-ee
是老余12 分钟前
本地可运行,jar包运行错误【解决实例】:通过IDEA的maven package打包多模块项目
java·maven·intellij-idea·jar
crazy_wsp13 分钟前
IDEA怎么定位java类所用maven依赖版本及引用位置
java·maven·intellij-idea
.Ayang15 分钟前
tomcat 后台部署 war 包 getshell
java·计算机网络·安全·web安全·网络安全·tomcat·网络攻击模型
red_redemption20 分钟前
自由学习记录(23)
学习·unity·lua·ab包
一直学习永不止步21 分钟前
LeetCode题练习与总结:最长回文串--409
java·数据结构·算法·leetcode·字符串·贪心·哈希表