使用 Lua 协程模拟 Golang 的 go defer 编程模式
封装 go 函数
在 使用 Lua 协程处理异步回调函数 中已经介绍
这里简要列下:
- 封装 go 函数
---go 函数创建并启动一个协程 ---@param _co_task function @函数原型 fun(_co:thread) function go(_co_task)local co = coroutine.create(_co_task) -- 创建的协程是暂停的coroutine.resume(co, co) -- 调用 coroutine.resume 激活协程执行 end - 封装项目中异步函数
---封装 c_model.c_foo 异步函数,成为协程函数 ---@param _co thread @协程对象 ---@return boolean,string function co_foo(_co)c_model.c_foo(function(_ok, _result)coroutine.resume(_co, _ok, _result) -- 2. 回调函数被调用后,激活本协程继续执行。并把_ok, _result传递给 yieldend)return coroutine.yield() -- 1. 主动放弃运行,本协程被切换出去 end - 使用例子
---test顺序编写代码,解决回调函数造成同块逻辑被撕裂的例子 ---@param _co thread @协程对象 function test(_co)for i = 1, 10, 1 dolocal ok, result = co_foo(_co) -- co_foo 会先 yield 切出;内部回调被执行时, resume 重新切回来继续执行print(ok, result)end end-- 启动 test 协程 go(test)
封装 defer
defer 的特点有以下:
- 协程正常退出能被执行
- 协程异常退出能被执行
- 同个协程内可以多次调用 defer
- defer 被执行时,按出栈顺序被执行
defer 多次执行
首先定义 defer 函数,让它具备能多次被调用:
function defer(_co_wrap, h)table.insert(_co_wrap.defer_handlers, h)
end
因为要对 defer 的函数句柄做保持,以便退出时执行。包裹了下 co 对象:
---@class co_wrap
---@field co thread
---@field defer_handlers fun(_co_error:co_error)[]
同时定义下让 defer 的函数知道是否有错误的对象:
---@class co_error
---@field ok boolean
defer 被执行时,按出栈顺序被执行
function invoke_defer_handlers(_co_wrap, _co_error)for i=#_co_wrap.defer_handlers, 1, -1 dolocal h = _co_wrap.defer_handlers[i]xpcall(h, function(err) print(err) end, _co_error)end
end
协程异常时,能被执行
Lua 协程异常,通过 coroutine.resume 捕获,并返回错误信息
因此主要封装下 coroutine.resume :
function coroutine_resume(_co_wrap, ...)local ok, errmsg = coroutine.resume(_co_wrap.co, ...)if not ok theninvoke_defer_handlers(_co_wrap, {ok=false}) -- 异常退出end
end
协程正常退出时,能被执行
function go(_co_task)local co = coroutine.create(function(_co_wrap)_co_task(_co_wrap)invoke_defer_handlers(_co_wrap, {ok=true}) -- 正常退出end)local cowrap = { co = co, defer_handlers = {} } ---@type co_wrapcoroutine_resume(cowrap, cowrap) -- 初创建的协程是暂停的,手动触发执行
end
以上就可以在 Lua 中完全 Golang 的方式编写协程代码了
协程间通信
由于项目中暂时是一根线程管理一个 lua_state 对象,因此暂时无需求多线程中的协程间的通信需求
待续
相关文章:
使用 Lua 协程模拟 Golang 的 go defer 编程模式
封装 go 函数 在 使用 Lua 协程处理异步回调函数 中已经介绍 这里简要列下: 封装 go 函数---go 函数创建并启动一个协程 ---param _co_task function 函数原型 fun(_co:thread) function go(_co_task)local co coroutine.create(_co_task) -- 创建的协程是暂停的…...
网络通信协议,UDP和TCP,初步了解
UDP(User Datagram Protocol)和TCP(Transmission Control Protocol)是两种常见的网络通信协议,用于在计算机网络中进行数据传输。 1. TCP:Transmission Control Protocol(传输控制协议…...
Golang | Leetcode Golang题解之第61题旋转链表
题目: 题解: func rotateRight(head *ListNode, k int) *ListNode {if k 0 || head nil || head.Next nil {return head}n : 1iter : headfor iter.Next ! nil {iter iter.Nextn}add : n - k%nif add n {return head}iter.Next headfor add > …...
美业SaaS系统多门店收银系统源码-【分润常见问题】讲解(一)
美业管理系统源码 博弈美业SaaS系统 连锁多门店美业收银系统源码 多门店管理 / 会员管理 / 预约管理 / 排班管理 / 商品管理 / 促销活动 PC管理后台、手机APP、iPad APP、微信小程序 ▶ 分润常见问题: 1、分润金额基数 所有分润计算的基数均为平台订单中各个商…...
Chatbot 在教育中的应用
Chatbot 在教育中的应用 基本信息 这篇博客主要介绍几篇Chatbot在教育领域中应用的文章,根据文章的侧重点不同,分为介绍教育理论,与介绍系统设计两类。从问题定义、技术方法、教育学理论、实验设计、结论证据几个方面概括各篇文章。 博…...
Apache和Nginx的区别以及如何选择
近来遇到一些客户需要lnmp环境的虚拟主机,但是Hostease这边的虚拟主机都是基于Apache的,尽管二者是不同的服务器软件,但是大多数情况下,通过适当的配置和调整两者程序也是可以兼容的。 目前市面上有许多Web服务器软件,…...
深入探索Element-UI:构建高效Web前端的利器
深入探索Element-UI:构建高效Web前端的利器 引言:前端框架的选择与Element-UI的定位一、Element-UI初探二、快速上手:安装与配置三、核心组件深度解析四、实用功能与进阶技巧五、性能优化与最佳实践六、实战案例分析七、与其他技术栈的集成 安…...
在Ubuntu 24.04 LTS (Noble Numbat)上安装nfs server以及nfs client
在Ubuntu 24.04 LTS (Noble Numbat)上,我使用的是最小化安装, 当然server版本的Ubuntu在安装的时候可能会有网络不通的问题,解决办法见如下文章: ubuntu 24.04 server 仅NAT模式上网设置静态IP设置-CSDN博客文章浏览阅读489次,点赞9次,收藏3次。在Ubuntu 24.04 上设置网…...
供应链|经典论文解读:(s,S) 策略在动态库存下的最优性
文章考虑了具有订购成本(由单位成本加上重新订购成本组成)的动态库存问题。具体而言,对于每个时期,系统在中期开始是做出一系列采购决策——这些采购有助于库存的积累,并在随后的周期被需求所消耗。每时期系统会产生各…...
Python从0到100(二十):文件读写和文件操作
一、文件的打开和关闭 有了文件系统可以非常方便的通过文件来读写数据;在Python中要实现文件操作是非常简单的。我们可以使用Python内置的open函数来打开文件,在使用open函数时,我们可以通过函数的参数指定文件名、操作模式和字符编码等信息…...
AI+客服行业落地应用
一、客服行业变迁 1.传统客服时代 (1)客服工作重复性高,技术含量低 (2)呼出效率低,客服水平参差不齐 (3)管理难度高,情绪不稳定 (4)服务质量…...
40 生产者消费者模型
生产者消费者模型 概念 为何要使用生产者消费者模型,这个是用过一个容器解决生产者和消费的强耦合问题。生产者和消费者之间不需要通讯,通过阻塞队列通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列…...
QT5之windowswidget_菜单栏+工具栏_核心控件_浮动窗口_模态对话框_标准对话框/文本对话框
菜单栏工具栏 新建工程基类是QMainWindow 1、 2、 3、 点.pro文件,添加配置 因为之后用到lambda; 在.pro文件添加配置c11 CONFIG c11 #不能加分号 添加头文件 #include <QMenuBar>//菜单栏的头文件 主窗口代码mainwindow.cpp文件 #include &q…...
Satellite, Aerial, and Underwater Communication Track(WCSP2023)
1.Dispersion Curve Extraction and Source Localization for Single Hydrophone by Combining Image Skeleton Extraction with Advanced Time-Frequency Analysis(图像骨架提取与先进时频分析相结合的单水听器色散曲线提取和源定位) 摘要:时频分析(TF…...
AtCoder Regular Contest 176(ARC176)A、B
题目:AtCoder Regular Contest 176 - tasks 官方题解:AtCoder Regular Contest 176 - editorial 参考:atcoder regular 176 (ARC176) A、B题解 A - 01 Matrix Again 题意 给一个nn的方格,给出m个坐标(x,y)m,在方格中…...
VTK —— 二、教程六 - 为模型加入3D微件(按下i键隐藏或显示)(附完整源码)
代码效果 本代码编译运行均在如下链接文章生成的库执行成功,若无VTK库则请先参考如下链接编译vtk源码: VTK —— 一、Windows10下编译VTK源码,并用Vs2017代码测试(附编译流程、附编译好的库、vtk测试源码) 教程描述 本…...
一种基于图搜索的全局/局部路径避障策略
系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录前言一种基于图搜索的全局/局部路径避障策略前言 认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长! 本文先对一种基于图搜索…...
LT2611UX四端口 LVDS转 HDMI2.0,带音频
描述LT2611UX 是一款面向机顶盒、DVD 应用的高性能 LVDS 至 HDMI2.0 转换器。LVDS输入可配置为单端口、双端口或四端口,具有1个高速时钟通道和3~4个高速数据通道,工作速率最高为1.2Gbps/通道,可支持高达19.2Gbps的总带宽。LT2611UX 支持灵活的…...
TypeError报错处理
哈喽,大家好,我是木头左! 一、Python中的TypeError简介 这个错误通常表示在方法调用时,参数类型不正确,或者在对字符串进行格式化操作时,提供的变量与预期不符。 二、错误的源头:字符串格式化…...
PHP的数组练习实验
实 验 目 的 掌握索引和关联数组,以及下标和元素概念; 掌握数组创建、初始化,以及元素添加、删除、修改操作; 掌握foreach作用、语法、执行过程和使用; 能应用数组输出表格和数据。 任务1:使用一维索引数…...
轻量级嵌入式按键驱动库:BartOS-button设计与多平台实践
1. BartOS-button 库概述BartOS-button 是为 BartOS 嵌入式实时操作系统项目配套开发的轻量级按键驱动库,专为资源受限的 IoT 终端设备设计。该库不依赖特定硬件抽象层(HAL),采用纯 C 实现,支持裸机(Bare-m…...
WPF装饰器(Adorner)的妙用:打造可交互的矩形标注控件(附避坑指南)
WPF装饰器实战:构建智能矩形标注控件的完整指南 在图像处理、数据标注或UI设计工具中,矩形标注功能几乎是标配需求。想象一下这样的场景:用户双击图片生成标注区域,通过拖拽调整位置,自由缩放大小,所有操作…...
智能CPU性能优化工具:释放处理器潜能的系统级解决方案
智能CPU性能优化工具:释放处理器潜能的系统级解决方案 【免费下载链接】CPUDoc 项目地址: https://gitcode.com/gh_mirrors/cp/CPUDoc 当你在游戏中遭遇帧率骤降、视频渲染耗时过长,或是多任务处理时系统响应迟滞,这些问题的根源往往…...
Java中调用PyTorch模型总失败?深度解析JNI桥接、序列化协议与内存泄漏的4重陷阱
第一章:Java AI 推理引擎集成示例在 Java 生态中集成 AI 推理能力,关键在于选择轻量、可嵌入且支持主流模型格式的推理引擎。本章以 Deep Java Library (DJL) 为例,演示如何在标准 Java 应用中加载 ONNX 模型并执行文本分类推理。环境准备与依…...
颈源性耳鸣,别当成耳部疾病治
耳朵里嗡嗡响、耳鸣不止,听力不受影响,去耳鼻喉科检查却查不出问题,吃药、调理也没有效果,这种耳鸣很可能不是耳部本身的问题,而是颈椎病变引发的颈源性耳鸣,也是极易被误诊的颈椎并发症。颈椎两侧分布着椎…...
opencv利用freetype写中文
1、ubuntu需要安装环境 sudo apt install libfreetype6-dev libharfbuzz-dev 2、opencv和opencv_contril编译,勾选下面按钮 3、下载字体库 https://github.com/StellarCN/scp_zh/tree/master/fonts 下载SimHei.ttf 4、代码 #include <opencv2/freetype.hpp…...
如何快速部署AI模型:免费本地化解决方案完整指南
如何快速部署AI模型:免费本地化解决方案完整指南 【免费下载链接】LocalAI mudler/LocalAI: LocalAI 是一个开源项目,旨在本地运行机器学习模型,减少对云服务的依赖,提高隐私保护。 项目地址: https://gitcode.com/GitHub_Trend…...
BGP路由优化实战:加速收敛,提升网络稳定性
BGP路由优化实战:加速收敛,提升网络稳定性在复杂的网络环境中,尤其是在大规模数据中心或跨区域互联的网络中,BGP(Border Gateway Protocol)路由协议的性能直接影响着网络的可用性和用户体验。BGP 作为互联网…...
从光波“数环”到材料“测温”:迈克尔逊干涉仪在热膨胀系数测量中的创新实践
1. 光波如何变成材料"温度计"? 第一次接触迈克尔逊干涉仪时,我盯着那些不断变化的彩色圆环发了半天呆。谁能想到这些看似简单的光环,竟然能精确测量出金属棒受热后百万分之一米级别的长度变化?这就像用一把能测量头发丝…...
如何高效提取与编辑Unity游戏资源?UABEA全功能解析与实践指南
如何高效提取与编辑Unity游戏资源?UABEA全功能解析与实践指南 【免费下载链接】UABEA UABEA: 这是一个用于新版本Unity的C# Asset Bundle Extractor(资源包提取器),用于提取游戏中的资源。 项目地址: https://gitcode.com/gh_mi…...
