Luat 功能开发教程(十四) 延时和定时器

2023-11-17

延时和定时器

简介

在luat脚本程序中,往往需要用到延时和等待等逻辑功能。例如,你想得到每隔30秒查询当前内存,这里就需要用到延时和定时器。在每次打印后加上一个30秒的定时器或者30秒的延迟,既可以实现这个功能。本篇文章将介绍2个延时函数和4个定时器函数以及一个判定定时器激活状态的函数,讲解这些函数如何使用以及在什么环境下使用。

API说明

详细的API介绍见sys API章节rtos API章节

实现流程

创建

sys.wait():

  • sys.wait(ms):既属于延时也属于定时器,但只能适用于任务函数中(task)。它功能就是被调用时挂起当前协程,等延时时间结束结束后再继续执行剩下的协程功能。原理是先去启动一个定时器,将当前的协程挂起。如需在定时器计时结束前退出,可使用coroutine.resume接口重新激活协程。
    创建也很简单,例子:sys.wait(1000) 会停止当前的协程任务,等1000ms后延时函数正常消亡,继续回来执行剩下脚本。

rtos.sleep():

  • rtos.sleep(ms):属于底层延时函数,可用于任何环境。函数执行原理:执行该函数会将操作系统中的Lua虚拟机任务挂起,在计时结束前无 法退出。
    创建示例:rtos.sleep(1000) 执行后,Lua虚拟机任务就会被挂起,1000ms后函数正常消亡,继续执行Lua虚拟机任务。

接下来是介绍定时器,共有四种定时器,他们各有各的特点。所以我们在使用时一定要记清楚这些定时器的特点,挑选适合当前程序需求的定时器使用。在luat脚本程序中,同时运行的定时器是有数量限制的。8910平台的Luat最多支持50个定时器,如何理解50个定时器?在下面的知识扩展里详细讲解了。sys.timerStart()和function sys.timerLoopStart()的返回值是定时器ID,这个可以用来判断是否为同一个
定时器。或者也可以通过定时器的回调函数和回调参数是否相同来判断。
sys.timerStart():

  • sys.timerStart(fnc,ms,…):属于定时器,单词定时器,适用场景不限定。第一个参数是回调函数,第二个是超时时间(ms),第三个是回调函数的参数,返回值是定时器ID。在创建前会查找当前开启的定时器,有相同定时器ID或者回调函数和回调参数相同时,就会关闭签一个定时器,再创建新的定时器,重新计时。

function sys.timerLoopStart():

  • function sys.timerLoopStart(fnc,ms, …):属定时器,循环定时器,适用场景不限定。用法特点同单此定时器几乎相同。唯一区别就是单此和多次循环。

sys.wait()(仅适用于task):

  • function sys.wait(ms):延时介绍过,属于延时也属于定时器。单次定时器,适用场景仅限定task内。

sys.waitUntil()(仅适用于task):

  • sys.waitUntil(id,ms):属于定时器,单次定时器,适用场景不限定。第一个参数是消息ID,第二个是超时间。sys.waitUntil()的特性与sys.timerStart()的完全一样,区别是sys.waitUntil()仅限于task内部使用。特性与详细介绍看下图。

image.png

消亡

自动消亡
  1. sys.timerStart:收到定时器事件,执行回调函数后,lib中自动消亡
  2. sys.timerLoopStart:收到定时器事件,每次执行回调函数后,lib中重新创建
  3. sys.wait:挂起的task收到定时器事件后,lib中自动消亡
  4. sys.waitUntil:挂起的task收到消息事件或者定时器事件后,lib中自动消亡
手动消亡
手动消亡有两种方式:sys.timerstop()和sys.timerstopAll()

1.sys.timerstop(val,…)
参数是定时器ID或者定时器的回调函数和回调参数。使用这个函数可以关闭指定的一个定时器。
返回值为nil
image.png

2.sys.timerstopAll(fnc)
功能:关闭sys.timerStart和sys.timerLoopStart创建的某一个回调函数的所有定时器
参数:需要关闭的定时器回调函数。
返回值:nil

image.png

已经消亡的定时器,再去执行stop不会产生异常

判断定时器状态

sys.timerlsActive()
功能:判断“通过timerStart或者timerStart创建的定时器”是否处于激活状态
参数:通过timerStart或者timerStart创建的定时器返回的定时器id或者回调函数与回调参数。

参数:
参数为回调函数与回调参数时,如果处于激活状态,则返回bool类型的true,否则返回nil。

返回值:
参数为定时器ID时,如果处于激活状态,则返回function类型的定时器回调函数,否则返回nil
例子:

local function timerCbFnc2(tag)
    log.info("timerCbFnc2",tag)
end

sys.timerStart(timerCbFnc2,5000,"test")

sys.taskInit(function()
    sys.wait(3000)
    log.info("after 3 senonds, timerCbFnc2 test isActive?",sys.timerIsActive(timerCbFnc2,"test"))
    
    sys.wait(3000)
    log.info("after 6 senonds, timerCbFnc2 test isActive?",sys.timerIsActive(timerCbFnc2,"test"))
end)

结果:
image.png


知识拓展

1.8910平台的Luat最多支持50个定时器,如何理解50个定时器?
看下列两端代码,猜测,最后分别还有几个定时器在运行。

sys.taskInit(function()
    for i=1,50 do
        sys.timerStart(function() end,1000)
    end
    log.info("不考虑其它代码中定时器的使用")
    log.info("运行到这里,同时存在多少个定时器?")
end)
sys.taskInit(function()
    for i=1,50 do
        sys.wait(1000)
    end
    log.info("不考虑其它代码中定时器的使用")
    log.info("运行到这里,同时存在多少个定时器?")
end)

第一段代码是创建50个回调函数相同,延时时间相同的单此定时器。通过前面的介绍可知, 如果回调函数和回调参数都相同的两个sys.timerStart()定时器,可视为同一定时器。当第一个sys.timerStart(function() end,1000)创建好后,再创建第二个sys.timerStart(function() end,1000)时,就会查找当前存在的定时器里,是否有相同的定时器,如果就就会将第一个关闭,创建第二个相同的定时器,并重新开始计时。所以第一个代码段最后吃剩一个定时器在运行。
第二段代码是创建50个sys.wait(1000)。当创建第一个sys.wait(1000)后,这个协程就会被挂起。1000ms后,继续执行剩下的程序,创建下一个sys.wait(1000)。所以,最后也只剩一个定时器。

下面这段代码,通过改变回调参数来同时创建50个sys.timerLoopStart(log.info,1000,“nCounter1”,i)。但看打印结果会发现,没到50个。因为打印出来的数量只是sys.timerLoopStart(log.info,1000,“nCounter1”,i)的数量,还有sys.wait(5000)等一些定时器没算在内。

    local function wait1()
    sys.wait(5000)
    for i=1,50 do
        sys.timerLoopStart(log.info,1000,"nCounter1",i)
    end
end

sys.taskInit(wait1)

示例

详细的API demo见The Timer demo章节

1.waitUntil()、wait()

  • waitUntil()和wait()sys.wait和sys.waitUntil只能用在task中,或者被task的主函数直接或者间接调用。
local function IndirectCall()
    sys.waitUntil("MSG_ID",5000)
end

sys.taskInit(function()
    sys.wait(5000)
    IndirectCall()
    log.info("sys.wait和sys.waitUntil只能用在task中")
    log.info("只能被task的主函数直接或者间接调用")
end)

2.timerStart()

  • timerStart()是单此定时器
local function publicTimerCbFnc(tag)
    log.info("publicTimerCbFnc",tag)
end

sys.timerStart(publicTimerCbFnc,8000,"first")
local timerId2 = sys.timerStart(publicTimerCbFnc,8000,"second")
sys.timerStart(publicTimerCbFnc,8000,"third")

3.timerLoopStart()

  • timerLoopStart()是循环定时器
local nCounter = 0

sys.taskInit(function ()
    while true do
        nCounter = nCounter+1
        sys.wait(1000)
    end
end)

sys.timerLoopStart(log.info,1000,"nCounter1",nCounter)
--sys.timerLoopStart(log.info,1000,"nCounter1",0)

sys.timerLoopStart(function() log.info("nCounter2",nCounter) end,1000)0,"first")

常见问题

1,定时器精度问题
Luat开发最小仅支持5毫秒的定时器,超时时间最小1ms(实际支持的最小时间是5ms,小于5ms的时间都被转化为5ms) 超时间最大0x7FFFFFFF(24.85天)。
另外毫秒级的定时器的误差较大,原因可参考Luat应用脚本运行框架

相关资料以及购买链接

延时和定时器 相关资料
sys API章节rtos API章节
延时和定时器demo说明
相关开发板购买链接
Air724UG开发板
Air724 开发板使用说明

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Luat 功能开发教程(十四) 延时和定时器 的相关文章

  • Lua:C++模块无法互相引用,未定义的符号

    我创建了两个模块 共享对象 CPU 和 SaveState 作为模拟器的一部分 两者都独立编译成 so 单独文件 并在运行时由 Lua 脚本使用 require 加载 IE SaveState require SaveState CPU r
  • lua检查多个值是否相等

    我喜欢用 Roblox 制作游戏 并用 lua 编写代码 在编写游戏时 我发现自己经常问一个值是否等于另一个值 这可能会产生很长的代码行 并且可能非常重复 例如 如果 x ClassName 衬衫 或x ClassName 附件 或x Cl
  • Lua 和序列化闭包

    我正在尝试序列化和反序列化 Lua 闭包 我的基本理解是下面的工厂应该生成闭包 并且Lua在函数和闭包之间没有太多区别 即没有类型 闭包 gt function ffactory x return function return x end
  • Lua 如何创建可用于变量的自定义函数?

    对于像 io close 这样的方法 你可以像这样使用它 file close 有没有办法创建一个像这样工作的自定义函数 您可以在变量上调用它 对我来说 我尝试使用它通过使用 string find 查找空格来将参数与文本文件分开 所以在文
  • 了解静态链接嵌入式lua环境中lua扩展dll的构建/加载

    我有一个相对复杂的 lua 环境 我试图了解以下内容如何工作 起始设置包括以下两个模块 主要应用 无lua环境 DLL 静态链接到lua lib 包括解释器 该 dll 被加载到主应用程序中 并运行 lua 控制台解释器和可从控制台访问的
  • Lua 中的内联条件(a == b ? "yes" : "no")?

    无论如何 Lua 中可以使用内联条件吗 Such as print blah a true blah nahblah Sure print blah a and blah or nahblah
  • 在 Corona sdk 上保存高分?

    我想保存游戏中创建的高分 并且当玩家点击高分按钮时可以在主菜单中看到 有人可以帮助我吗 您可以使用SQLITE https docs coronalabs com api library sqlite3 index html将高分保存到数据
  • 如何解密Lua字节码?

    早上好 我正在尝试破译 Moon 字节码 但我无法以任何方式 有人可以帮助我吗 我有这个 例如 code 27 76 117 97 81 0 1 4 4 4 8 0 如何将此字节码解密为文本 我已经在这里搜索 http www asciit
  • 为什么 LuaJIT 和 Lua 中的数字舍入格式不同?

    Using string format 据说遵循 Csprintf 在 LuaJIT 轮次中格式化数字与我尝试过的所有其他 Lua 解释器不同 lua v Lua 5 4 1 Copyright C 1994 2020 Lua org PU
  • Redis 排序集和解决关系

    我正在使用 Redis 排序集来存储我正在处理的项目的排名 我们没有预料到 我们想要如何处理关系 Redis 按字典顺序对具有相同分数的条目进行排序 但我们想要做的是对具有相同分数的所有条目给予相同的排名 例如在以下情况 redis 127
  • lua http套接字超时

    LuaSocket HTTP 模块文档说可以在 HTTP 连接上设置超时 可以设置以下常量来控制 HTTP 模块的默认行为 PORT 用于连接的默认端口 PROXY 用于连接的默认代理 TIMEOUT 设置所有I O操作的超时时间 USER
  • 什么时候适合使用Lua这样的嵌入式脚本语言

    我玩 魔兽世界 大约有两年了 我对用来编写插件的 Lua 很好奇 由于到目前为止我读到的有关 Lua 的内容都是 快 轻 和 这太棒了 所以我想知道如何以及何时使用它 您需要在系统中嵌入像 Lua 这样的脚本语言的典型情况是什么 当您需要最
  • 如何在 Lua 中实现 OO?

    Lua 没有内置对 OO 的支持 但它允许您自己构建它 您能否分享一些实现面向对象的方法 请为每个答案写一个例子 如果您有更多示例 请发布另一个答案 我喜欢将 OOP 视为容器 对象 内的数据封装以及可以使用该数据完成的操作子集 还有很多内
  • 安装Lua套接字库

    要么我太累了 要么我瞎了 我想学习 Lua 网络 因此我必须安装socketlib 所以我可以轻松地要求它 但我不知道我应该 要求 哪些文件 例子说 local socket require socket 但正如我所说 如果我使用 我不知道
  • 检查多个位置的值并仅在源唯一时返回匹配项

    假设我有一个清单Vendors 阿斯达 乐购 Spar 我有一个清单Sources 或者这个类比中的供应商 家乐氏 Kellogg 吉百利 Cadbury 雀巢 Nestle 强生 Johnsons 帮宝适 Pampers Simple 等
  • 比较 Lua 中的日期

    我有一个带有日期表的变量 如下所示 table day number 15 year number 2015 month number 2 如何获取当前日期与上述日期之间的天数 非常感谢 您可以使用os time 将表转换为秒并获取当前时间
  • 如何通过 C API 在自己的环境中执行不受信任的 Lua 文件

    我想通过调用在其自己的环境中执行不受信任的 lua 文件lua setfenv http pgl yoyo org luai i lua setfenv这样它就不会影响我的任何代码 该函数的文档仅解释了如何调用函数 而不解释如何执行文件 目
  • Lua C API:初始化结构体 C 中的变量矩阵

    我正在尝试使用 Lua C API 创建一个用户数据 并在其中关联一个元表 我将在其中收集矩阵 我无法得到的是如何将初始化矩阵的每个分量设置为零 我按照我的描述编译我的 Lua 模块 C 代码here https stackoverflow
  • 关闭 Löve2D 中的抗锯齿功能

    我在用着L ve2D http love2d org用于编写一个小游戏 L ve2D 是 Lua 的开源游戏引擎 我遇到的问题是 当您在非整数位置绘制精灵时 某些抗锯齿过滤器会自动应用于精灵 love graphics draw sprit
  • Lua中有状态迭代器和无状态迭代器的区别

    Lua中无状态和有状态迭代器有什么区别 请详细解释一下 什么时候需要使用无状态 什么时候需要使用另一种 我需要例子来理解这个概念 首先让我们就一个定义达成一致 在 Lua 中 迭代器是function 类似对象 每次调用时都会返回序列中的下

随机推荐

  • 基础理解之SESSION

    SESSION是服务器端的一种会话机制 当客户端的请求服务器创建一个SESSION时 服务器会先检测该请求里面是否包含一个惟一的sesionid 如果是 说明服务器已经为该用户创建过SESSION 只要按照该sesionid检索出该用户的s
  • 在钉钉上怎么手写_大庆市第十中学

    有关直播的那些事儿 2020 停课不停学 十中在行动 根据大庆市教育局关于网络教学工作的要求和指导意见 我校将于3月2日全面开展网络教学工作 虽然网络直播教学与线下日常教学主旨都是一样的 但由于形式的差异 对于很少体验过网络直播教学的老师来
  • 红米ac2100 刷openwrt以及刷回记录

    redmiac2100 刷机 参考 手动升级漏洞固件 https wwx lanzoux com i6iqxhqp98f 或者百度网盘链接 https pan baidu com s 1H355Ym9p TLrVOux2w2b7Q 提取码
  • Flutter开发之——Icon图标

    一 概述 Icon是支持material design的一系列图标 Icon类似于iconfont即字体图标 它是将图标做成字体文件 然后通过指定不同的字符显示不同图片 二 Icon说明 2 1 说明 在字体文件中 每一个字符都对应一个位码
  • Android内存管理

    Android内存泄露 全解析和处理办法 http www jianshu com p bf159a9c391a
  • 产品运行所需的信息检索失败。请重新安装xshell

    产品运行所需的信息检索失败 请重新安装xshell 很久没有应用Xshell进行远程服务器连接了 由于需要应用远程云计算资源 因此有需要使用这个软件 但是在今天的使用过程中出现了 问题 打开Xshell之后 找到可执行文件之后 点击运行 管
  • 【CQOI 2015】任务查询系统

    题目 传送门 题目描述 最近实验室正在为其管理的超级计算机编制一套任务管理系统 而你被安排完成其中的查询部分 超级计算机中的任务用三元组 Si Ei Pi 描述 Si Ei Pi 表示任务从第 Si 秒开始 在第 Ei 秒后结束 第 Si
  • 电脑开不了机启动不了

    故障现象 解决办法 1 先不要操作别的 首先想想开机之前做过什么操作 更新过什么 补丁 漏洞 软件 还是别的等等 2 重启操作系统 在开机的时候不停地按F8键 如果不停地按之后出现了一个黑底白字的菜单 可以最后一次配置试试 不行可以进入系统
  • 服务器CPU经常跑高是什么原因

    服务器在使用过程中 经常会遇见这样的情况 在长时间使用之后 系统运行会越来越慢 卡的情况 查询后台进程 CPU占用以超过90 那么高的CPU使用率 都是会由哪些因素导致的呢 1 散热故障 如机房散热不足 温度过热或者驱动故障 导致温度太高
  • html新闻滚动效果,js实现滚动新闻效果

    code js cn a display block font size 15px line height 18px text decoration none color 333 font family Arial font size 12
  • 机器学习-泛化能力笔记

    1 什么是泛化能力 在机器学习方法中 泛化能力通俗来讲就是指学习到的模型对未知数据的预测能力 在实际情况中 我们通常通过测试误差来评价学习方法的泛化能力 2 泛化误差的定义 大家马上应该发现 这个不是损失函数的期望吗 没错 泛化误差就是所学
  • C++多线程(七):unique_lock详解

    目录 unique lock取代lock guard unique lock的第二个参数 std adopt lock std try to lock std defer lock unique lock的成员函数 成员函数lock 成员函
  • 多线程(十):总结

    本章用来处理一下之前遗漏的很多问题 在多线程那一章 很多常见面试题都没有讲 这里再来补充一下 HashTable HashMap ConcurrentHashMap 之间的区别 HashTable HashMap ConcurrentHas
  • BurpSuite武器库打造之环境搭建和API介绍(上)

    0x00前言 在使用Burp Suite 以下简称Burp 来开展渗透工作的途中可能需要验证一些脑洞大开的想法 但Burp自带的功能可能无法满足你的需求 于是你迫切需要一个高度定制化的插件来实现这个功能 经查阅你得知除了Java还可以通过配
  • 无法清空剪切板,另一程序正在使用剪切板,无法复制东西了

    这种情况一般都是因为 有道或者其他翻译软件在你复制过程中不断把东西添加到剪切板中导致你无法继续添加新的东西到剪切板中 策略 关闭有道词典 在设置中将复制查词 取消即可
  • DBeaver连接MySQL提示“Public Key Retrieval is not allowed”的解决办法

    一 问题描述 一段时间没使用DBeaver 再次打开DBeaver连接MySQL提示 Public Key Retrieval is not allowed Public Key Retrieval is not allowed 不允许进行
  • HIVE简单介绍和了解

    用于解决海量日志数据的分析 hive是基于Hadoop的一个数据仓库工具 可以将结构化的数据文件映射为一张数据库表 并提供完整的sql查询功能 可以将sql语句转换为MapReduce任务进行运行 其优点是学习成本低 可以通过类SQL语句快
  • Linux开发工程师是吃青春饭的吗?

    Linux开发工程师怎么样 都说程序员是吃青春饭 Linux开发工作35岁之后还能做吗 坦白说 如果程序员在35岁的时候 工作经验 与刚毕业的时候差别不大 则其不可替代性就不高 很难在大龄时具备足够竞争力 大龄程序员 跟应该以专业洞识 理解
  • InterBase 6.5的新特性 (转)

    InterBase 6 5的新特性 转 more InterBase 6 5的新特性XML namespace prefix o ns urn schemas microsoft com Office office gt 作者 Bill T
  • Luat 功能开发教程(十四) 延时和定时器

    目录 延时和定时器 简介 API说明 实现流程 创建 消亡 自动消亡 手动消亡 判断定时器状态 知识拓展 示例 常见问题 相关资料以及购买链接 延时和定时器 简介 在luat脚本程序中 往往需要用到延时和等待等逻辑功能 例如 你想得到每隔3