sys - sys库
一. sys
模块核心功能概述
sys
模块是 LuatOS 的核心库,提供 任务管理、定时器、事件机制 等基础功能,是开发网络通信、传感器控制等应用的核心工具。
sysplus
是 sys
模块的扩展库,主要提供 增强的任务消息机制;
sys
模块中,使用publish和waitUntil组合时,在publish某个消息之前,要求waitUntil语句已经在阻塞等待这个消息,对代码编程的时序要求比较高,稍微不注意,就有可能出现waitUntil等不到消息的问题;
sysplus
模块的sendMsg和WaitMsg,增加了缓冲队列存储,可以很好的解决这个问题;
建议 sys
和 sysplus
一起阅读。
二. API 函数详解
(1) 任务管理
sys.taskInit(func, arg1, arg2, ..., argN)
- 功能:创建并启动一个任务协程。
-
参数:
func
:任务入口函数(可接受参数arg1
~argN
)。arg1
~argN
:传递给func
的参数,可选。- 返回值:任务线程号(
thread
类型),目前LuatOS开放的接口,没有地方可以用到这个返回值,大家不用过多关心这个返回值以及thread
类型。 - 示例:
sys.taskInit(function(a, b, c)
log.info("task", a, b, c) -- 打印 task A B N
end, "A", "B", "N")
sys.wait(timeout)
- 功能:Task 协程等待指定时长。
- 参数:
timeout
(毫秒,必须 >0)。 - 返回值:
nil
- 示例:
sys.taskInit(function()
while true do
log.info("Task Running")
sys.wait(1000) -- 每秒执行一次
end
end)
sys.waitUntil(topic, timeout)
- 功能:Task 协程等待指定时长或者特定的 topic。
-
参数:
topic
:事件名称(字符串)。timeout
:超时时间(毫秒)。-
返回值:
-
成功:
true
及事件数据。 - 超时:
false
。 - 示例:
sys.taskInit(function()
local result, ip, adapter = sys.waitUntil("IP_READY", 30000)
if result then
log.info("Network Ready", ip, adapter)
else
log.error("Timeout")
end
end)
(2) 定时器管理
sys.timerStart(func, timeout, arg1, ..., argN)
- 功能:创建一个定时器。
- task的任务处理函数以及非task的任务处理函数中都能使用;
- func和arg1, ..., argN共同标识了唯一的一个定时器;
- 如果使用sys.timerStart接口重新创建一个同样的定时器(func和arg1, ..., argN),则之前正在运行的定时器会自动被关掉,新定时器重新计时开始运行
- 参数:
func
:回调函数。timeout
:超时时间(毫秒)。arg1
~argN
:传递给func
的参数。
- 返回值:定时器 ID(
number
类型)。 - 示例:
local tid = sys.timerStart(function(a, b)
log.info("Timer Triggered", a, b)
end, 1000, "A", "B")
sys.timerLoopStart(func, timeout, arg1, ..., argN)
- 功能:创建一个循环定时器。
- task的任务处理函数以及非task的任务处理函数中都能使用;
- func和arg1, ..., argN共同标识了唯一的一个定时器;
- 如果使用sys.timerLoopStart接口重新创建一个同样的定时器(func和arg1, ..., argN),则之前正在运行的定时器会自动被关掉,新定时器重新计时开始运行
- 参数:
func
:回调函数。timeout
:超时时间(毫秒)。arg1
~argN
:传递给func
的参数。
- 返回值:定时器 ID(
number
类型)。 - 示例:
sys.timerLoopStart(function()
log.info("Loop Timer")
end, 5000)
sys.timerStop(id)
- 功能:关闭指定定时器。
- 参数:
id
(定时器 ID)。 - 返回值:
nil
。 - 示例:
local tcount = 0
local tid
tid = sys.timerLoopStart(function(a, b, c)
log.info("task", a, b, c) -- 1000毫秒后才会执行, 打印 task A B N
if tcount > 10 then
sys.timerStop(tid)
end
tcount = tcount + 1
end, 1000, "A", "B", "N")
sys.timerStopAll(fnc)
- 功能:关闭同一回调函数
fnc
的所有定时器。 - 参数:
fnc
(回调函数)。 - 返回值:
nil
。 - 示例:
local function callback()
log.info("Timer Callback")
end
sys.timerStart(callback, 1000)
sys.timerLoopStart(callback, 2000)
sys.timerStopAll(callback) -- 停止所有使用 callback 的定时器
(3) 事件机制
sys.publish(topic, arg1, arg2, ..., argN)
- 功能:向指定事件通道发布消息。
-
参数:
topic
:事件名称(字符串)。arg1
~argN
:附加数据。- 返回值:
nil
。 - 示例:
sys.publish("DATA_READY", {temp=25, humidity=60})
sys.subscribe(topic, func)
- 功能:订阅一个 topic 通道。
-
参数:
topic
:事件名称。func
:回调函数(参数为arg1
~argN
)。- 返回值:
nil
。 - 示例:
local function handler(data)
log.info("Received Data", data)
end
sys.subscribe("DATA_READY", handler)
sys.unsubscribe(topic, func)
- 功能:取消订阅一个 topic 通道。
- 参数:同
sys.subscribe
。 - 返回值:
nil
。 - 示例:
sys.unsubscribe("DATA_READY", handler)
(4) 系统控制
sys.run()
- 功能:启动系统主循环,需放在
main.lua
最后。 - 参数:无。
- 返回值:
nil
。 - 示例:
-- main.lua 的最后
sys.run()
三. 使用建议与注意事项
(1)任务管理
- 避免阻塞:
- 长时间操作需配合
sys.wait()
或者sys.waitUntil()
或者syspluys.waitMsg()
分段执行,避免任务阻塞其他协程。
- 长时间操作需配合
(2)定时器
-
ID 管理:
- 使用
sys.timerStop(id)
时需传入定时器 ID,或通过sys.timerStopAll
批量停止。 -
参数传递:
-
定时器回调函数可通过
arg1
~argN
接收参数。
- 使用
(3)事件机制
-
解耦设计:
- 使用
sys.publish
和sys.subscribe
实现模块间解耦通信。 -
避免冲突:
-
确保事件
topic
全局唯一,避免命名冲突。
- 使用
(4)系统控制
sys.run()
必须存在:- 必须在
main.lua
结尾调用,否则程序无法进入主循环。
- 必须在
四. 示例代码
示例 1:任务与定时器
-- 创建任务
sys.taskInit(function()
while true do
log.info("Task Running")
sys.wait(1000)
end
end)
-- 单次定时器
sys.timerStart(function()
log.info("Single Timer Triggered")
end, 2000)
-- 循环定时器
sys.timerLoopStart(function()
log.info("Loop Timer Running")
end, 5000)
-- 主循环
sys.run()
示例 2:事件发布与订阅
-- 订阅事件
sys.subscribe("DATA_READY", function(data)
log.info("Received Data:", data)
end)
-- 模拟发布事件
sys.timerStart(function()
sys.publish("DATA_READY", {temp=25, humidity=60})
end, 3000)
-- 主循环
sys.run()
五. 常见问题
-
Q:如何停止所有定时器?
- 使用
sys.timerStopAll(fnc)
或遍历所有定时器 ID 调用sys.timerStop
。 -
Q:
sys.waitUntil
的超时如何处理? -
返回
false
时需主动处理超时逻辑。 -
Q:任务协程如何退出?
-
让函数执行完成, 例如 return, 或执行到最后一行,自动退出和清理。
- 使用