元素码农
基础
UML建模
数据结构
算法
设计模式
网络
TCP/IP协议
HTTPS安全机制
WebSocket实时通信
数据库
sqlite
postgresql
clickhouse
后端
rust
go
java
php
mysql
redis
mongodb
etcd
nats
zincsearch
前端
浏览器
javascript
typescript
vue3
react
游戏
unity
unreal
C++
C#
Lua
App
android
ios
flutter
react-native
安全
Web安全
测试
软件测试
自动化测试 - Playwright
人工智能
Python
langChain
langGraph
运维
linux
docker
工具
git
svn
🌞
🌙
目录
▶
Lua语言基础
▶
环境搭建
安装Lua解释器
配置开发环境
第一个Lua程序
▶
基本语法
变量与数据类型
运算符与表达式
控制结构
▶
数据结构
表(Table)详解
数组与迭代
字符串处理
▶
Lua高级编程
▶
函数编程
函数定义与调用
闭包与作用域
高阶函数应用
▶
元表与元方法
元表基础
操作符重载
继承与对象系统
▶
协程编程
协程基础
生产者-消费者模式
协程调度实践
▶
Lua应用实践
▶
游戏开发
Lua与游戏引擎集成
AI脚本实现
热更新机制
▶
系统编程
Lua与C交互
扩展库开发
性能优化技巧
▶
实用工具开发
配置文件解析
自动化测试框架
网络编程基础
发布时间:
2025-03-24 12:08
↑
☰
# Lua协程基础 本文将介绍Lua中的协程(Coroutine)概念和基本用法,帮助你理解这种强大的并发编程特性。 ## 协程概念 协程是一种协作式多任务处理的机制,它允许一个函数执行到某个点后暂停,并在之后从该点继续执行。 ### 1. 协程与线程的区别 - 协程是协作式的,而线程是抢占式的 - 协程由程序显式调度,而线程由操作系统调度 - 同一时刻只有一个协程在运行 - 协程更轻量级,开销更小 ### 2. 基本概念 ```lua -- 创建协程 local co = coroutine.create(function() print("协程开始") coroutine.yield() -- 暂停执行 print("协程结束") end) -- 恢复协程执行 coroutine.resume(co) -- 输出:协程开始 coroutine.resume(co) -- 输出:协程结束 ``` ## 协程操作 ### 1. 创建协程 ```lua -- 使用create创建 local co1 = coroutine.create(function() print("使用create创建的协程") end) -- 使用wrap创建 local co2 = coroutine.wrap(function() print("使用wrap创建的协程") end) -- 区别: -- create返回协程对象,需要使用resume调用 -- wrap返回函数,可以直接调用 coroutine.resume(co1) -- 使用resume调用 co2() -- 直接调用 ``` ### 2. 传递参数和返回值 ```lua -- 向协程传递参数 local co = coroutine.create(function(a, b) print("收到参数:", a, b) local sum = a + b return sum -- 返回值 end) -- resume可以传递参数并接收返回值 local status, result = coroutine.resume(co, 10, 20) print("结果:", result) -- 输出:结果:30 ``` ### 3. yield的使用 ```lua -- yield可以暂停执行并返回值 local co = coroutine.create(function() for i = 1, 3 do print("协程执行:", i) coroutine.yield(i) -- 返回当前值 end end) -- 循环恢复协程 while coroutine.status(co) ~= "dead" do local status, value = coroutine.resume(co) print("yield返回值:", value) end ``` ## 协程状态 协程有以下几种状态: - suspended:暂停状态 - running:正在运行 - normal:正常状态(可恢复) - dead:已结束 ```lua -- 查看协程状态 local co = coroutine.create(function() print("当前状态:", coroutine.status(coroutine.running())) coroutine.yield() end) print("初始状态:", coroutine.status(co)) -- suspended coroutine.resume(co) -- running print("yield后状态:", coroutine.status(co)) -- suspended coroutine.resume(co) -- 结束执行 print("结束状态:", coroutine.status(co)) -- dead ``` ## 实际应用 ### 1. 生产者-消费者模式 ```lua -- 生产者协程 local function producer() local i = 0 while true do i = i + 1 coroutine.yield(i) -- 产生数据 end end -- 消费者函数 local function consumer(prod) local co = coroutine.create(prod) return function() -- 返回迭代器 local status, value = coroutine.resume(co) return status and value end end -- 使用示例 local next_value = consumer(producer) for i = 1, 5 do print("消费数据:", next_value()) end ``` ### 2. 异步操作模拟 ```lua -- 模拟异步操作 local function async_operation(callback) local co = coroutine.create(function() print("开始异步操作") coroutine.yield() -- 模拟异步等待 print("异步操作完成") if callback then callback() end end) return { start = function() coroutine.resume(co) end, finish = function() coroutine.resume(co) end } end -- 使用示例 local operation = async_operation(function() print("回调函数执行") end) operation.start() -- 开始操作 -- 这里可以执行其他代码 operation.finish() -- 完成操作 ``` ### 3. 迭代器实现 ```lua -- 使用协程实现迭代器 local function range(from, to, step) return coroutine.wrap(function() for i = from, to, (step or 1) do coroutine.yield(i) end end) end -- 使用示例 for n in range(1, 5) do print(n) end ``` ## 常见问题解答 ### Q1: 为什么需要协程? 协程适用于以下场景: - 实现迭代器 - 异步编程 - 状态机 - 协作式多任务 ### Q2: 协程和多线程的选择? ```lua -- 适合使用协程的场景 local function download_files(files) for _, file in ipairs(files) do -- 下载文件的操作 coroutine.yield(file) -- 可以暂停并报告进度 end end -- 适合使用多线程的场景 -- 密集计算、并行处理等需要真正并发的场景 ``` ### Q3: 如何处理协程错误? ```lua -- 使用pcall包装resume local function safe_resume(co, ...) local status, result = coroutine.resume(co, ...) if not status then print("协程错误:" .. result) return nil end return result end ``` ## 下一步 现在你已经掌握了Lua协程的基础知识,可以继续学习[生产者-消费者模式](/article/lua/advanced/producer-consumer)来了解协程的实际应用模式。 ## 参考资源 - [Lua 5.4 参考手册 - 协程](http://www.lua.org/manual/5.4/manual.html#6.2) - [Programming in Lua - 协程](http://www.lua.org/pil/9.html) - [Lua协程教程](http://lua-users.org/wiki/CoroutinesTutorial)