sysplus - sys库的强力补充
一. sysplus
模块核心功能概述
sysplus
是 sys
模块的扩展库,主要提供 增强的任务消息机制;
sys
模块中,使用publish和waitUntil组合时,在publish某个消息之前,要求waitUntil语句已经在阻塞等待这个消息,对代码编程的时序要求比较高,稍微不注意,就有可能出现waitUntil等不到消息的问题;
sysplus
模块的sendMsg和WaitMsg,增加了缓冲队列存储,可以很好的解决这个问题;
sys
模块是 LuatOS 的核心库,提供 任务管理、定时器、事件机制 等基础功能,是开发网络通信、传感器控制等应用的核心工具。
建议 sysplus
和 sys
一起阅读。
二. API 函数详解
(1) 任务管理
sysplus.taskInitEx(func, taskName, cbFun, ...)
- 功能:创建一个有taskName的任务线程。
-
参数:
func
:任务处理函数。taskName
:任务名称(字符串,必须全局唯一,不同的任务使用的taskName不要重复,否则逻辑运行会错乱)。cbFun
:回调函数,用于处理非目标消息(目标消息是指sysplus.waitMsg(taskName, msg, timeout)等待的msg消息,除此之外,通过sysplus.sendMsg(taskName, msg)给这个taskName发送的其他消息都属于非目标消息)。...
:传递给func
的可变参数。- 返回值:任务线程号(
thread
类型),目前LuatOS开放的接口,没有地方可以用到这个返回值,大家不用过多关心这个返回值以及thread
类型。 - 示例:
local function taskFunc()
while true do
-- 等待消息"task1_event"或者10秒超时
local msg = sysplus.waitMsg("task1", "task1_event", 10000)
if msg then
-- msg.target为"task1_event"
log.info("waitMsg", "收到task1_event消息", msg.target)
else
log.info("waitMsg", "10秒超时,没有收到task1_event消息")
end
end
end
sysplus.taskInitEx(taskFunc, "task1", function(msg)
log.warn("Received non-target message:", msg)
end)
sysplus.taskDel(taskName)
- 功能:删除由 taskInitEx 创建的任务线程。
- 参数:
taskName
(任务名称)。 - 返回值:无。
- 示例:
sysplus.taskDel("task1") -- 删除名为 "task1" 的任务
(2) 事件消息管理
sysplus.waitMsg(taskName, target, timeout)
- 功能:等待指定目标消息,支持超时控制。
-
参数:
taskName
:任务名称(接收消息的任务 ID)。target
:目标消息标识(字符串或nil
表示接收任意消息)。timeout
:超时时间(毫秒,nil
表示无限等待)。-
返回值:
-
成功:返回消息
table
(包含target
、arg2
、arg3
、arg4
等参数)。 - 超时:返回
false
。 - 注意:会自动注册全局函数
sys_wait
,需避免命名冲突。 - 示例:
local msg = sysplus.waitMsg("task1", "data", 2000)
if msg then
log.info("Received:", msg.target, msg.arg2)
else
log.warn("Timeout")
end
sysplus.sendMsg(taskName, target, arg2, arg3, arg4)
- 功能:向指定任务发送消息。
-
参数:
taskName
:目标任务名称。target
:消息标识(接收方waitMsg
的target
匹配项)。arg2
~arg4
:附加参数(可选)。- 返回值:
true
(成功)或false
(失败)。 - 注意:自动注册全局函数
sys_send
,需避免命名冲突。 - 示例:
-- 向任务 "task1" 发送目标为 "data" 的消息,携带参数 100 和 "ok"
sysplus.sendMsg("task1", "data", 100, "ok")
sysplus.cleanMsg(taskName)
- 功能:清除指定任务的消息队列。
- 参数:
taskName
(任务名称)。 - 返回值:无。
- 示例:
sysplus.cleanMsg("task1") -- 清空 "task1" 的消息队列
三. 使用场景与示例代码
示例 1:任务创建与消息通信
-- 定义任务函数
local function taskFunc()
while true do
local msg = sysplus.waitMsg("task1", "data") -- 无限等待 "data" 消息
if msg then
log.info("Received Data:", msg.arg2, msg.arg3)
end
end
end
-- 创建任务
sysplus.taskInitEx(taskFunc, "task1", function(msg)
log.warn("Unknown message:", msg)
end)
-- 主线程发送消息
sysplus.sendMsg("task1", "data", 42, "Hello from main")
示例 2:超时控制与消息清理
-- 等待消息并处理超时
local msg = sysplus.waitMsg("task2", "timeout_test", 1000)
if not msg then
log.error("Message timeout!")
sysplus.cleanMsg("task2") -- 清理消息队列
end
四. 注意事项
1. 任务命名唯一性:
taskName
必须全局唯一,避免重复导致任务覆盖或冲突。
2. 全局函数注册:
sysplus.waitMsg
和sysplus.sendMsg
会自动注册全局函数sys_wait
和sys_send
,需确保不与其他代码冲突。
3. 消息队列限制:
- 消息队列容量有限,需及时处理消息或调用
sysplus.cleanMsg
避免队列溢出。
4. 协程与阻塞:
sysplus.waitMsg
是阻塞操作,只能在使用sysplus.taskInitEx创建的任务的主函数中使用。
5. 参数传递限制:
sendMsg
最多支持 4 个参数(target
+ 3 个附加参数),需按需设计消息结构。
五. 常见问题
1. Q:如何处理消息队列溢出?
- 定期调用
sysplus.cleanMsg
或在cbFun
中清理无效消息。
2. Q:waitMsg
的超时时间如何设置?
timeout
为nil
表示无限等待,0
表示立即返回,负数同nil
。
3. Q:任务被删除后如何清理资源?
- 使用
sysplus.taskDel
同时会自动清理相关消息队列。