元素码农
基础
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:10
↑
☰
# Lua协程调度实践 本文将介绍如何在Lua中实现一个简单的协程调度器,帮助你理解如何管理和调度多个协程。 ## 调度器基础 ### 1. 基本结构 ```lua -- 创建调度器 local Scheduler = {} Scheduler.__index = Scheduler function Scheduler.new() return setmetatable({ tasks = {}, -- 任务列表 timers = {}, -- 定时器列表 current = nil -- 当前运行的协程 }, Scheduler) end -- 添加任务 function Scheduler:addTask(func) local co = coroutine.create(func) table.insert(self.tasks, co) return co end -- 运行调度器 function Scheduler:run() while #self.tasks > 0 do local task = table.remove(self.tasks, 1) self.current = task local success, result = coroutine.resume(task) if not success then print("任务错误:" .. result) elseif coroutine.status(task) ~= "dead" then -- 如果任务没有结束,重新加入队列 table.insert(self.tasks, task) end self.current = nil end end ``` ### 2. 任务控制 ```lua -- 任务让出控制权 function Scheduler:yield() coroutine.yield() end -- 等待指定时间 function Scheduler:sleep(seconds) local co = self.current if not co then return end local wakeTime = os.time() + seconds table.insert(self.timers, { time = wakeTime, task = co }) coroutine.yield() end ``` ## 任务队列 ### 1. 优先级队列 ```lua -- 优先级任务 local PriorityTask = {} PriorityTask.__index = PriorityTask function PriorityTask.new(func, priority) return setmetatable({ co = coroutine.create(func), priority = priority or 0 }, PriorityTask) end -- 优先级调度器 local PriorityScheduler = {} PriorityScheduler.__index = PriorityScheduler function PriorityScheduler.new() return setmetatable({ tasks = {}, current = nil }, PriorityScheduler) end function PriorityScheduler:addTask(func, priority) local task = PriorityTask.new(func, priority) table.insert(self.tasks, task) table.sort(self.tasks, function(a, b) return a.priority > b.priority end) return task end function PriorityScheduler:run() while #self.tasks > 0 do local task = table.remove(self.tasks, 1) self.current = task local success, result = coroutine.resume(task.co) if not success then print("任务错误:" .. result) elseif coroutine.status(task.co) ~= "dead" then table.insert(self.tasks, task) table.sort(self.tasks, function(a, b) return a.priority > b.priority end) end self.current = nil end end ``` ### 2. 事件驱动 ```lua -- 事件驱动调度器 local EventScheduler = {} EventScheduler.__index = EventScheduler function EventScheduler.new() return setmetatable({ tasks = {}, events = {}, current = nil }, EventScheduler) end function EventScheduler:addTask(func) local task = coroutine.create(func) table.insert(self.tasks, task) return task end function EventScheduler:waitForEvent(eventName) local co = self.current if not co then return end self.events[eventName] = self.events[eventName] or {} table.insert(self.events[eventName], co) coroutine.yield() end function EventScheduler:emitEvent(eventName, ...) local handlers = self.events[eventName] if not handlers then return end for _, handler in ipairs(handlers) do table.insert(self.tasks, handler) end self.events[eventName] = {} end ``` ## 定时器系统 ### 1. 基本定时器 ```lua -- 定时器调度器 local TimerScheduler = {} TimerScheduler.__index = TimerScheduler function TimerScheduler.new() return setmetatable({ tasks = {}, timers = {}, current = nil }, TimerScheduler) end function TimerScheduler:setTimeout(func, delay) local co = coroutine.create(func) local timer = { task = co, time = os.time() + delay } table.insert(self.timers, timer) return timer end function TimerScheduler:setInterval(func, interval) local co = coroutine.create(function() while true do func() self:sleep(interval) end end) table.insert(self.tasks, co) return co end function TimerScheduler:run() while #self.tasks > 0 or #self.timers > 0 do -- 检查定时器 local now = os.time() for i = #self.timers, 1, -1 do local timer = self.timers[i] if timer.time <= now then table.remove(self.timers, i) table.insert(self.tasks, timer.task) end end -- 运行任务 if #self.tasks > 0 then local task = table.remove(self.tasks, 1) self.current = task local success, result = coroutine.resume(task) if not success then print("任务错误:" .. result) elseif coroutine.status(task) ~= "dead" then table.insert(self.tasks, task) end self.current = nil end end end ``` ## 实际应用 ### 1. 游戏循环 ```lua -- 游戏调度器 local GameScheduler = TimerScheduler.new() -- 游戏实体 local Player = { x = 0, y = 0, speed = 1 } -- 更新玩家位置 GameScheduler:setInterval(function() Player.x = Player.x + Player.speed print(string.format("玩家位置:(%d, %d)", Player.x, Player.y)) end, 1) -- 生成敌人 GameScheduler:setInterval(function() print("生成新敌人") end, 5) -- 运行游戏 GameScheduler:run() ``` ### 2. 异步任务处理 ```lua -- 异步任务调度器 local AsyncScheduler = EventScheduler.new() -- 模拟异步操作 local function asyncOperation(name, duration) return function() print(name .. "开始") AsyncScheduler:sleep(duration) print(name .. "完成") AsyncScheduler:emitEvent(name .. "_完成") end end -- 添加任务 AsyncScheduler:addTask(asyncOperation("任务1", 2)) AsyncScheduler:addTask(asyncOperation("任务2", 1)) -- 等待任务完成 AsyncScheduler:addTask(function() AsyncScheduler:waitForEvent("任务1_完成") print("任务1处理完成") AsyncScheduler:waitForEvent("任务2_完成") print("任务2处理完成") print("所有任务完成") end) -- 运行调度器 AsyncScheduler:run() ``` ## 常见问题解答 ### Q1: 如何选择合适的调度器? 根据应用场景选择: - 简单任务:基本调度器 - 优先级任务:优先级调度器 - 事件驱动:事件调度器 - 定时任务:定时器调度器 ### Q2: 如何处理任务错误? ```lua -- 错误处理示例 local function safeResume(co, ...) local success, result = coroutine.resume(co, ...) if not success then print("错误:" .. result) print(debug.traceback(co)) return false end return true end ``` ### Q3: 如何实现任务取消? ```lua -- 可取消的任务 function Scheduler:cancelTask(task) for i, t in ipairs(self.tasks) do if t == task then table.remove(self.tasks, i) return true end end return false end ``` ## 下一步 现在你已经掌握了Lua的协程调度,可以继续学习[游戏开发](/article/lua/practice/game-engine)来了解如何在实际项目中应用这些知识。 ## 参考资源 - [Lua 5.4 参考手册](http://www.lua.org/manual/5.4/manual.html) - [Programming in Lua](http://www.lua.org/pil/9.html) - [Lua并发编程](http://www.lua.org/gems/)