前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >代码片段|Lua使用协程制作定时器

代码片段|Lua使用协程制作定时器

作者头像
keyle
发布2024-11-01 12:22:06
发布2024-11-01 12:22:06
12200
代码可运行
举报
文章被收录于专栏:礼拜八不工作礼拜八不工作
运行总次数:0
代码可运行

Lua 中的协程(coroutine)是一种轻量级的线程,它们共享同一个全局状态,但拥有独立的栈空间。协程允许在 Lua 中实现非阻塞的多任务处理,而无需操作系统的线程调度。这使得协程非常适合用于实现像定时器、网络请求、异步 I/O 等场景。

Lua 的协程使用 coroutine 模块来创建和管理。下面是关于 Lua 协程的一些基本概念和用法,文末给出一个定时器的Demo;

1. 创建协程

使用 coroutine.create 函数来创建一个新的协程。该函数接受一个函数作为参数,并返回一个协程对象。

代码语言:javascript
代码运行次数:0
复制
lualocal function myCoroutine()
    print("Inside coroutine")
end

local co = coroutine.create(myCoroutine)

2. 恢复协程

使用 coroutine.resume 函数来恢复一个已经暂停的协程。当协程被恢复时,它会从上次暂停的位置继续执行,直到遇到 coroutine.yield 或返回。

代码语言:javascript
代码运行次数:0
复制
lua-- 恢复协程
coroutine.resume(co)

3. 协程状态

coroutine.status 函数用于获取协程的当前状态。可能的状态有 "running"(协程正在运行)、"suspended"(协程已暂停)和 "normal"(协程已完成执行)。

代码语言:javascript
代码运行次数:0
复制
lualocal status = coroutine.status(co)
print(status)  -- 输出协程的状态

4. 协程中的 yield

coroutine.yield 函数用于在协程中主动让出控制权,将执行权交还给调用 coroutine.resume 的代码。这允许实现非阻塞操作,如等待用户输入或等待网络响应。

代码语言:javascript
代码运行次数:0
复制
luafunction myCoroutine()
    print("Before yield")
    coroutine.yield()
    print("After yield")
end

local co = coroutine.create(myCoroutine)
coroutine.resume(co)  -- 输出 "Before yield" 并暂停
coroutine.resume(co)  -- 恢复并从 yield 后继续,输出 "After yield"

5. 协程中的返回

协程可以像普通函数一样返回一个值。当协程返回时,coroutine.resume 会返回 true 以及协程返回的值。

代码语言:javascript
代码运行次数:0
复制
luafunction myCoroutine()
    return "Hello from coroutine"
end

local co = coroutine.create(myCoroutine)
local success, result = coroutine.resume(co)
if success then
    print(result)  -- 输出 "Hello from coroutine"
end

6. 多重 yield

一个协程可以在其生命周期中多次 yield,每次 yield 都会将控制权交还给调用者,直到协程被再次 resume

代码语言:javascript
代码运行次数:0
复制
luafunction myCoroutine()
    for i = 1, 3 do
        print("Count:", i)
        coroutine.yield()
    end
end

local co = coroutine.create(myCoroutine)
for i = 1, 3 do
    coroutine.resume(co)
end

7. 协程和主线程

主线程(或称为“根协程”)也是一个协程,因此它可以使用 coroutine.yield 来让出控制权,尽管这通常不是一个好主意,因为它会暂停整个程序的执行。

注意事项

  • 协程应该避免使用过多的内存,因为它们的栈空间是独立的,每个协程都有自己的栈。
  • 协程不应该进行阻塞操作,因为这会阻止整个程序的执行,直到阻塞操作完成。
  • coroutine.yield 在一个协程中可以有多个,用于在协程的不同点处暂停和恢复执行。

通过合理使用协程,Lua 程序可以实现高效且易于管理的并发行为。

8. 协程制作定时器Demo

wrap会返回一个function,等价于coroutine.resume(co,timeCnt)

代码语言:javascript
代码运行次数:0
复制
timer = {}
local getTime = os.time
local nextTime = 0
local currentTime = 0
local timeCnt = 0

function timer.IntervalFunc()
    while timeCnt > 0 do
        while nextTime > currentTime
        do
            if currentTime ~= getTime() then
                currentTime = getTime()
            end
        end
        nextTime = getTime() + 1
        timeCnt = timeCnt - 1
        print(timeCnt+1)
    end
end

function timer.StartTimer(default_vaule)
    timeCnt = default_vaule
    nextTime = getTime() + 1
    -- local co = coroutine.create(timer.IntervalFunc)
    -- coroutine.resume(co,timeCnt)
    coroutine.wrap(timer.IntervalFunc,timeCnt)()
end

timer.StartTimer(3)
return timer
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-05-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 礼拜八不工作 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 创建协程
  • 2. 恢复协程
  • 3. 协程状态
  • 4. 协程中的 yield
  • 5. 协程中的返回
  • 6. 多重 yield
  • 7. 协程和主线程
  • 注意事项
  • 8. 协程制作定时器Demo
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档