【Lua坑】Lua协程coroutine无法正常完整执行问题

news/2024/9/18 20:26:30 标签: lua, 开发语言, 协程, 对象池

问题:发现Lua协程执行到一半,突然被掐断了一样等到了设定的时间没有正常执行协程后续代码!非必现bug,若发生大概率在高频率使用协程时易触发。

LuaFramework或xLua uLua都自带有协程coroutine,而且基本都使用对象池缓存协程对象,当我们稍微不小心就会引起对象池的问题,也就是持有一个已入池的对象。

1、所有持有写法必须要在使用完协程时手动置空持有对象。

self.co = coroutine.start(function()
        coroutine.waitxxx
        self.co = nil
        ... ...
end)

2、究极神坑!究极神坑!究极神坑!重要的事情说三遍!
当你想持有协程对象时,一定要保证协程执行过至少1次延迟(无论是延迟1帧还是多少秒)例如下面出问题的代码:

local cnt = param --外部传入param参数
local co
co = coroutine.start(function()
        for i = 1, cnt do
                coroutine.waitxxx
                ... ...
        end
​​​​​​​        ... ...
        table.removebyvalue(coTable, co)
end)
table.insert(coTable, co)

不要在意细节,param一定是整数,但可能为0,问题就出在cnt被赋予了一个0,导致for循环没有执行过1次,从而导致协程没有进行过1次延迟waitxxx,所以协程函数体会立即执行完成,关键点是table.removebyvalue(coTable, co)先于table.insert(coTable, co)执行,而table.insert(coTable, co)后执行就加入了1个已回收入对象池的对象。(持有已入池对象行为)后面发生什么就是你会发现有些协程好像无法正常执行完成,明明上一个还在正常输出,下一个就突然消失了,也就是存在这种持有已入池对象行为,要把这种行为全部抹除才能恢复正常,或者直接干脆不用对象池了,可能性能开销会上升点,不然就得排查全部相关的持有代码,将上面代码加一行延迟1帧或延迟渲染结束就能解决问题(保证至少执行过1次延迟!)

local cnt = param --外部传入param参数
local co
co = coroutine.start(function()
        coroutine.waitforendofframe()--延迟渲染结束帧
        for i = 1, cnt do
                coroutine.waitxxx
                ... ...
        end
​​​​​​​        ... ...
        table.removebyvalue(coTable, co)
end)
table.insert(coTable, co)

我试过在remove后直接将co=nil,insert时检查co~=nil再进行,还是会有异常情况。
如果Lua协程本身是没有对象池缓存机制的,那就不会存在我说的问题。

实际上这个问题就是对象池的坑,只是演变到了协程这里让人很抓狂 


http://www.niftyadmin.cn/n/5664474.html

相关文章

C# winform 字符串模糊查询,也就是查找子串

C# winform 字符串模糊查询,也就是查找子串。 1. String.Contains() Contains() 方法通常使用内部的 IndexOf() 实现,所以它的性能与 IndexOf() 相近。这是一个非常快速的方法,适合于一般的应用场景。 2. String.IndexOf() IndexOf() 方法…

SOLIDWORKS® 2025 新增功能 - SIMULATION

SOLIDWORKS Simulation 1常规弹簧连接 • 通过定义仅轴向、各向同性或正交各向异性弹簧, 在曲面之间轻松创建自定义弹簧连接。 • 通过添加自定义合规性提高仿真性能和精度。 优点 利用新的弹簧连接功能, 实现更简单、更逼真的仿真 设置。 2增强了…

新手学习Python第九天-新手笔记 速学中

现在是北京时间06:55,早上06:44到达实验室,开始学习。对,昨天陪室友考教师资格证了,溜溜达达一天很舒服,两周一次的放松感。这几天和未来几天的压力真的很大,有很多要去学习的,比如C…

深入浅出:使用Retriever实现高效文档检索

引言 在数据驱动的现代社会,快速准确地检索信息变得至关重要。Retriever作为一种接口,能够根据无结构的查询返回相关文档,其应用十分广泛。本文将深入探讨Retrievers的工作原理、如何使用及其在实际应用中的挑战和解决方案。 主要内容 什么…

Java---网络编程

一.网络的基本概念 1.指令 二.网络模型 1.七层模型 七层模型,也称为OSI(Open System Interconnection)参考模型,是国际标准化组织(ISO)制 定 的一个用于计算机或通讯系统间互联的标准体系。它是一个七层…

哪些人群适合做旅游卡项目?首选这5类人群!

在旅游市场蓬勃发展的今天,旅游卡项目成为了一个充满潜力的创业选择。那么,哪些人群适合涉足这个领域呢?重点首选这5类人群: 一、自由职业者 自由职业者拥有灵活的工作时间安排,这是他们从事旅游卡项目的一大优势。他…

2024年适合培训服务企业的7款CRM盘点

培训服务行业在线索管理、客户管理、数据分析、项目管理、师资管理和课程管理等方面,使用CRM可以事半功倍,最重要的是,可以用数据说话,找到降本增效的方向。 下面对培训服务行业常用测CRM做个盘点,包括国内比较头部的…

配置环境-keil

配置keil -- 先将keil安装配置好,包括库 一、STM32 -- STM32是意法半导体(意大利)采用ARM公司设计的内核,设计一系列32位单片机芯片。 1、STM32开发的几种方式 2、STM32寄存器和库函数版本的工程创建 新建文件夹 复制相关文件…