Lua协程

Lua 的协程 为什么会出现? 一开始大家想要同一时间执行那么三五个程序,大家能一块跑一跑。特别是UI什么的,别一上计算量比较大的玩意就跟死机一样。于是就有了并发,从程序员的角度可以看成是多个独立的逻辑流。内部可以是多cpu并行,也可以是单cpu时间分片,能快速的切换逻辑流,看起来像是大家一块跑的就行。 但是一块跑就有问题了。我计算到一半,刚把多次方程解到最后一步,你突然插进来,我的中间状态咋办,我用来储存的内存被你覆盖了咋办 阅读详情

协程是非抢断式的多线程方式,看上去像多线程,其实如同名字说的—协程,在协调多段程序的运行并且各自的代码段是有自己独立的变量的cache。本文主要通过实例将协程的处理讲清楚。
resume和yield是一个很好的桥梁,将代码段之间方便的传输参数。

接口函数:

函数参数说明
coroutine.createf创建协程
coroutine.resumeco [, val1, ···]开启或者继续一个协程
coroutine.running无返回是否协程在运行,或者返回nil当被主线程调用时
coroutine.statusco返回协程状态:running,suspended,normal,dead
coroutine.wrapco原生态创建协程
coroutine.yield…挂起正在执行的

coroutine.wrap有点特别,这个是我摘抄文档中的解释:
类似 coroutine.create , coroutine.wrap 这个函数也将创建一个 coroutine , 但是它并不返回 coroutine 本身,而是返回一个函数取而代之。一旦你调用这个返回函数,就会切入 coroutine 运行。 所有传入这个函数的参数等同于传入 coroutine.resume 的参数。 coroutine.wrap 会返回所有应该由除第一个(错误代码的那个布尔量) 之外的由 coroutine.resume 返回的值。 和 coroutine.resume 不同, coroutine.wrap 不捕获任何错误; 所有的错误都应该由调用者自己传递。

官方的一个实例:

 function foo (a)
   print("foo", a)
   return coroutine.yield(2*a)
 end

 co = coroutine.create(function (a,b)
       print("co-body", a, b)
       local r = foo(a+1)
       print("co-body", r)
       local r, s = coroutine.yield(a+b, a-b)
       print("co-body", r, s)
       return b, "end"
 end)

 print("main", coroutine.resume(co, 1, 10))
 print("main", coroutine.resume(co, "r"))
 print("main", coroutine.resume(co, "x", "y"))
 print("main", coroutine.resume(co, "x", "y"))

输出结果:

>lua -e "io.stdout:setvbuf 'no'" "test.lua" 
co-body 1   10
foo 2
main    true    4
co-body r
main    true    11  -9
co-body x   y
main    true    10  end
main    false   cannot resume dead coroutine

调用顺序:

Created with Raphaël 2.1.0主线程主线程协程协程resume(co, 1, 10) 主线程挂起,唤起协程foo (1+1)coroutine.yield(2*2) 协程挂起,主线程唤醒return resume()->主线程获得2*2返回值coroutine.resume(co, "r")主线程挂起,唤起协程local r = foo(a+1)触发resume("r")参数赋值给local rcoroutine.yield(a+b, a-b)协程挂起,主线程唤醒,将会1+10,1-10print("main", coroutine.resume(co, "r"))将yield的参数输出coroutine.resume(co, "x", "y")主线程挂起,唤起协程local r, s = coroutine.yield(a+b, a-b)主线程中输入的"x","y"变量将会被赋值给r,s由于协程已经执行全部的流程最终将会把流程交回给主线程,协程将会变成dead态print("main", coroutine.resume(co, "x", "y"))将会触发协程函数返回值的打印X,协程已经不再工作状态,所以造成程序直接返回,服务器不能唤起

看完这个例子之后,其实可以看出来这两个线程其实一直在配合做事情。当resume被调用的时候,主线程就暂停了活动,将运行的权限交给了coroutine来做事。当coroutine yield的时候,将会直接触发自己的coroutine暂停,激活主线程的resume的return,接着做事。所以理论上对一个coroutine的调用,函数中有几个yield,主线程的代码中需要些多少个resume函数,否则如果主线程只对coroutine做一次resume。但是这个也不会造成太多的内存问题,协程对象被释放掉之后也将不会存在内存泄露
下面就举个例子来做一下测试说明此问题。


function first_phase(a)
    -- coroutine first phase
    return coroutine.yield( a + 1 )
end


collectgarbage('collect')
print(string.format("after full garbage-collection cycle, memory: %d k",collectgarbage('count')))

for i = 1, 100 do
    local co = coroutine.create( function ( a, b )
        local l_a, l_b = a, b
        local m1 = first_phase(a)
        -- coroutine second phase
        local m2 = coroutine.yield( m1 + 1 )
        -- coroutine third phase
        return input * b
    end)

    first_return = coroutine.resume( co, 10, 8 )
    -- without to call resume let coroutine to finish

    if i == 99 then
        collectgarbage('collect')
        print(string.format("after full garbage-collection cycle, memory: %d k",collectgarbage('count')))
    end
end

collectgarbage('collect')
print(string.format("after full garbage-collection cycle, memory: %d k",collectgarbage('count')))

输出:

after full garbage-collection cycle, memory: 20 k
after full garbage-collection cycle, memory: 21 k
after full garbage-collection cycle, memory: 20 k

这个说明了问题,就是其实在coroutine的Up-value的数据都是被保存在coroutine对象中。一旦释放掉这些对象,其Up-value数据也将会被回收,即使是这个coroutine状态还是在suspended之下也没有关系。

C++ 与 Lua 的协程交互 Lua 语言不支持真正的多线程,即不支持共享内存的抢占式线程。这样的模式能减少一些多线程的问题。多线程的问题源于线程抢占和共享内存,而如果非抢占式线程或者不使用共享内存则能避免多线程问题,Lua 同时支持这两种方案。Lua 语言的线程是协作式的,即协程,可以避免因不可预知的线程切换带来的问题。Lua 状态间内存不共享,所以各个状态相互独立运行,可以并行操作。Github传送门(如果对你有所帮助或喜欢的话,赏个star吧,码字不易,请多多支持)如果觉得本篇博文对你有所启发或是解决了困惑,。 阅读详情

相关推荐

Lua 协程

Lua里的协程是一个原来没见过的东西,Python的Gevent也是一个基于coroutine的python网络开发框架。性能据说很不错。 协同的一个关键特征是它可以不断颠倒调用者与被调用者之间的关系 协程和一般多线程的区别是,一般多线程由系统决定该哪个线程执行,是抢占式的,而协程是由每个线程自己决定自己什么时候不执行,并把执行权主动交给下一个线程。 协程是用户空间线程,操作系统其存在一无所知

yolo模型训练找我,AI游戏合作找我 7739

【Lua学习笔记】Lua进阶——协程

在Unity中,由于游戏是单线程的(这是为了其他线程不阻塞进程),因此我们常常需要使用协程。

milu_ELK的博客 3799

基于mediapipe的动作捕捉和unity的人物模型驱动

用到的人体关键点检测的算法是Google开发的基于深度学习的实时多媒体套件,汇集了人体、手部、人脸关键点追踪、物体检测、物体识别等多个流行的视觉任务的成果。整套 Mediapipe正如其名字,专门为便携设备上的多媒体应用设计,模型非常小,在笔记本手机上也能实时跑,跨平台、跨语言。mediapipe实时性是没什么问题。但是是以牺牲了质量为代价的,这种关键点检测一般是用来做动作识别,类似于运动app跳绳计数、判定瑜伽动作标不标准这种。用单目视觉来做人物模型的驱动,总差点意思。

qq_58484580的博客 5727

lua协程

Lua 协程(Coroutine)是一种轻量级的线程,也被称为协作式多线程。与操作系统管理的线程不同,协程是由程序自身来控制调度的,属于协作式多任务处理机制。这意味着协程只有在显式地让出执行权时,才会暂停执行,将控制权交给其他协程,而不是由操作系统强制切换。轻量级:创建和销毁协程的开销远小于创建和销毁线程。非抢占式调度:程序员可以精确控制协程的执行流程,避免了线程同步和锁带来的复杂性。Lua 协程通过协作式挂起和恢复机制,提供了轻量级的多任务处理能力。

m0_45371381的博客 1168

基于Coze平台从零构建AI智能体:以测试用例生成为例的实战指南

在人工智能技术快速发展的今天,大语言模型(LLM)和提示词工程(Prompt Engineering)已成为构建智能应用的核心技术。其原理在于通过自然语言指令引导模型完成特定任务,其技术价值在于极大地降低了AI应用开发的门槛,使非专业开发者也能快速实现想法。这一技术广泛应用于自动化办公、智能客服、内容生成等场景。本文聚焦于字节跳动旗下的Coze平台,该平台通过可视化工作流编排和预置技能,将上述技术封装为易用的工具。文章以“根据产品需求文档(PRD)自动生成测试用例”这一具体场景为例,详细拆解了从需求分析、工

weixin_30617695的博客 337

立创电赛C题:基于STM32的三端口DC-DC变换器设计与MPPT算法实现

本文详细解析了2021年立创电赛C题——基于STM32的三端口DC-DC变换器设计。文章从题目要求出发,系统阐述了采用双DC-DC电路(分别负责MPPT追踪与稳压)的硬件架构,并重点讲解了以STM32为核心、结合PID控制与扰动观察法(MPPT算法)的软件实现方案,为备赛者提供了完整的软硬件设计思路与调试经验。

weixin_42588877的博客 222

协程编程的奥秘:Lua中协程使用的全面解析与技巧分享

协程基础。 生产者-消费者问题。 协程相关API说明。 将协程用作迭代器。 事件驱动式编程。

Lion_Long的博客 2335

Raspberry Pi 4 ARM Trusted Firmware 技术解析

摘要: 本文详细介绍了在树莓派4(Raspberry Pi 4)上移植ARM可信固件(TF-A)的实现方案与安全考量。该移植专注于BL31功能,作为非安全世界(如Linux内核)的启动桥梁,支持加载EL2级别程序。文章分析了启动流程、内存映射设计,并对比了RPi3与RPi4的关键差异,指出当前版本缺乏硬件级安全内存保护的局限性。此外,提供了构建指南、配置说明及设备树自动修补的实现细节,强调通过config.txt简单配置即可启动64位内核。该方案充分利用树莓派原有GPU固件流程,兼顾兼容性与简易性。

Linux内核架构师 932

Unity的协程和Lua的协程

本文分享Unity的协程和Lua的协程 协程(Coroutine)在我们游戏开发中有着比较重要的地位. 协程全名协同程序, 和线程不同, 协程是依附于主线程执行的, 相当于在主线程上夺取了一定的执行时间片. 也可以理解为在主线程的调用之外开辟了一个单独的调用栈, 并在协程消亡之前能保存内部信息和与其它协程共享公用信息. 协程实质是运行在主线程, 代码仍然是同步执行, 只是在某些点被挂起然后重新进行主线程其它代码的执行, 之后重新进入协程时可以从离开点继续执行. 这点和递归有些类似. 协程的核心概念有挂起和恢

木头圈 2024

ZeroClaw安装、使用方法详细全解

ZeroClaw 是一个用 Rust 编写的轻量级、高性能、完全自主的 AI 助手运行时框架

洛星核的博客 616

2023华为od机试C卷【启动多任务排序】C++ 实现

一个应用启动时,会有多个初始化任务需要执行,并且任务之间有依赖关系,例如A任务依赖B任务,那么必须在B任务执行完成之后,才能开始执行A任务。现在给出多条任务依赖关系的规则,请输入任务的顺序执行序列,规则采用贪婪策略,即一个任务如果没有依赖的任务,则立刻开始执行,如果同时有多个任务要执行,则根据任务名称字母顺序排序。

MISAYAONE的博客 883

Lua协程实现原理

相关 API API 传入参数 返回值 说明 API 传入参数 返回值 说明 create(f) 函数,作为协程运行的主函数 返回创建的协程 如果还需要运行,需要使用resume操作 resume(co,[val1,…]) 传入第一个参数是create函数返回的协程,剩下的参数是传递给协程运行的参数。 分两种情况,resume成功的情况下返回true以及上一次 yield函数传入的参数;失败情况下返回false,以及错误信息 第一次执行resume操作时,会从creat

zebin的博客 4307

Simulink智能驾驶场景探索:自动泊车系统设计与验证

自动泊车系统(APS)传感器模块:用于检测车辆周围的障碍物和其他车辆的位置。路径规划模块:根据传感器数据生成最优的泊车路径。控制器模块:根据路径规划结果生成转向角、速度等控制信号。执行器模块:根据控制器生成的信号调整车辆的方向盘、油门和刹车。在本实例中,我们将使用超声波传感器和摄像头来检测车辆周围的环境,并使用PID控制器实现自动泊车功能。通过本教程,我们介绍了如何使用 Simulink 进行自动泊车系统的仿真。背景介绍:理解自动泊车系统及其在智能驾驶中的应用。所需工具和环境。

MHD0815的博客 505

lua协程 unity_XLua 之 Lua 协程 与 Unity 协程互通

前言:最近在摸索用XLua 在 Unity 中进行全Lua 开发。然后就遇到了协程的问题。我想在 Lua 侧开启一个 Unity 的协程,该怎么做呢?一开始我先去翻 XLua 的文档,我记得之前我看文档是看到过协程介绍的。但是快速翻了一遍后没找到(后来又找到了,本文最后会进行讲解)。然后就开始了自己的摸索。什么是协程?协程 是 协同程序 的简写。有过 Unity 或者 Lua 基础的朋友应该都已经...

weixin_32445333的博客 486

Halcon 色彩标定:RGB空间下实现白平衡与CCM矩阵合成静态HDR图像

摘要 本文介绍了一种基于Halcon的色彩校正方法,结合白平衡与灰轴约束最小二乘法实现精准颜色还原。方法分为三步:1)自动定位色卡区域并提取灰阶块计算白平衡增益;2)通过前三列色块建立测量值与标准值的映射关系;3)引入灰轴约束条件求解色彩校正矩阵(CCM),确保中性灰区域不偏色。算法采用中位数计算白平衡增益以提高鲁棒性,并通过旋转校正处理色卡倾斜问题。实验表明,该方法能有效消除相机采集的系统色偏,适用于颜色测量、表面检测等机器视觉场景。文末提供了完整代码实现。

LIN943168247的博客 404

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Lua中的协程

lua中协程学习及坑点分享

NeverBeBack 1004

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

lua协程实例

一、lua协程的和c++中协程的区分 1. lua 程序设计中的关于lua多线程以及协程的概述 上述说的意思我认为就是 lua的协程类似于但是不等同于真正意义的多线程(同时执行一些操作);我做过测试,同时创建1000个协程并执行(代码执行的速度可以忽略不计的),所有的创建成功的时间不是在同一毫秒内,所以,协程之间按照顺序并且不会相互影响的。 2. 协程几个主要函数 ...

In_Zihuatanejo的博客 897

lua协程 unity_在Lua中使用类Unity协程

Unity中的协程是通过Update驱动的,通过yield return来打断,在声明周期中回调执行,也就是resume。在Lua里面其实只需要我们自己进行yield然后我们自己在update里面resume就和Unity的协程一毛一样了。不过Lua的协程好像不支持像Unity一样的中断:yield break……只能自己注意别在协程里写无限循环就好。不过还没有看过效率怎么样……协程管理部分req...

weixin_30974667的博客 607

【Lua基础系列】协程

【Lua基础系列】协程 大家好,我是Lampard~~ 欢迎来到Lua进阶系列的博客 前文再续,书接上一回。今天和大家讲解一下lua中的协程 (一) 什么是协程 Lua 协同程序(coroutine)与线程(这里的线程指的是操作系统的线程)比较类似:拥有独立的堆栈,独立的局部变量,独立的指令指针,同时又与其它协同程序共享全局变量和其它大部分东西。 一个多线程程序可以同时运行几个线程(并发执行、抢占),而协程却需要彼此协作地运行,...

Lampard的博客 6441

【Lua进阶系列】协程

【Lua进阶系列】协程 大家好,我是Lampard猿奋~~ 欢迎来到Lua进阶系列的博客,今天和大家分享一下lua中关于协程的知识点 (一)什么是协程 Lua 协同程序(coroutine)与线程比较类似:拥有独立的堆栈,独立的局部变量,独立的指令指针,同时又与其它协同程序共享全局变量和其它几乎一切资源。 一个多线程程序可以同时并行运行几个线程,而协程却需要彼此协作地运行,并非真正的多线程。即一个多协程程...

Lampard的博客 1033

Lua协程介绍

协程(coroutine)是一种程序组件,它允许执行代码在不同的点暂停和恢复,从而实现协作式的多任务处理。与传统的线程不同,协程不是由操作系统调度的,而是由程序自身控制的。因此,协程提供了一种轻量级的并发机制,适用于需要多任务但不需要真正并行的场景。

lzh824359508的博客 879

lua 的协程池写法

闲来,写了一个协程池 目标是能实现写成复用,而不需要反复去生成新的协程 具体见代码注释 代码如下: local co_running = assert(coroutine.running) local co_create = assert(coroutine.create) local co_yield = assert(coroutine.yield) local co_...

weixin_42445065的博客 1898

【lua学习】8.协程

1 数据结构和宏1.1 协程的状态码1.2 协程的执行状态码1.3 lua_State 协程结构体2 C API2.1 lua_newthread 新建一个协程,压栈,返回这个新协程2.2 luaE_freethread 释放一个协程L12.3 lua_status 获取协程的错误码2.4 lua_resume 唤醒一个协程,nargs为参数个数,返回值为协程状态码2.5 lua_yield 挂起一个协程3 Lua API3.1 协程模块的注册3.1.1 luaL_register(L, LUA_COLI.

qq_18138105的博客 1741
上一篇: 顺序编程介绍
下一篇: hiredis读写(同步式)
erlang_hell
博客等级 码龄14年 57粉丝 89原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值