Lua co-routines

2023-11-13

http://stackoverflow.com/questions/7206411/lua-co-routines

I'm trying to get an understanding of how I can use co-routines to "pause" a script and wait until some processing is done before resuming.

Perhaps I'm looking at co-routines in the wrong way. But my attempt is structured similar to the example given in this answer.

The loop in loop.lua never reaches a second iteration, and hence never reaches the i == 4condition required to exit the running loop in the C code. If I do not yield in loop.lua, then this code performs as expected.

main.cpp

#include <lua/lua.hpp>

bool running = true;

int lua_finish(lua_State *) {
    running = false;
    printf("lua_finish called\n");
    return 0;
}
int lua_sleep(lua_State *L) {
    printf("lua_sleep called\n");
    return lua_yield(L,0);
}

int main() {
    lua_State* L = lua_open();
    luaL_openlibs(L);

    lua_register(L, "sleep", lua_sleep);
    lua_register(L, "finish", lua_finish);

    luaL_dofile(L, "scripts/init.lua");

    lua_State* cL = lua_newthread(L);
    luaL_dofile(cL, "scripts/loop.lua");

    while (running) {
        int status;
        status = lua_resume(cL,0);
        if (status == LUA_YIELD) {
            printf("loop yielding\n");
        } else {
            running=false; // you can't try to resume if it didn't yield
            // catch any errors below
            if (status == LUA_ERRRUN && lua_isstring(cL, -1)) {
                printf("isstring: %s\n", lua_tostring(cL, -1));
                lua_pop(cL, -1);
            }
        }
    }

    luaL_dofile(L, "scripts/end.lua");
    lua_close(L);
    return 0;
}

loop.lua

print("loop.lua")

local i = 0
while true do
    print("lua_loop iteration")
    sleep()

    i = i + 1
    if i == 4 then
        break
    end
end

finish()

EDIT: Added a bounty, to hopefully get some help on how to accomplish this.

asked  Aug 26 '11 at 14:42
dcousens
2,289 1 20 48
 

2 Answers

up vote 2 down vote accepted
+50

Return code 2 from lua_resume is a LUA_ERRRUN. Check the string on the top of the Lua stack to find the error message.

A similar pattern has worked for me, though I did use coroutine.yield instead of lua_yield and I'm in C rather than C++. I don't see why your solution wouldn't work

On your resume call, it's not clear if you're over simplifying for an example, but I'd make the following changes in your while loop:

int status;
status=lua_resume(cL,0);
if (status == LUA_YIELD) {
  printf("loop yielding\n");
}
else {
  running=false; // you can't try to resume if it didn't yield
  // catch any errors below
  if (status == LUA_ERRRUN && lua_isstring(cL, -1)) {
    printf("isstring: %s\n", lua_tostring(cL, -1));
    lua_pop(cL, -1);
  }
}

Edit 2:

For debugging, add the following before you run your resume. You've got a string getting pushed on the stack somewhere:

int status;
// add this debugging code
if (lua_isstring(cL, -1)) {
  printf("string on stack: %s\n", lua_tostring(cL, -1));
  exit(1);
}
status = lua_resume(cL,0);

Edit 3:

Oh good grief, I can't believe I didn't see this already, you don't want to run luaL_dofile when you're going to yield because you can't yield a pcall directly as best I know, which is what happens in the dofile (5.2 will pass it through, but I think you still need the lua_resume). Switch to this:

luaL_loadfile(cL, "scripts/loop.lua");
answered  Aug 26 '11 at 20:00
BMitch
10.8k 2 18 34
 
 
The error code 2 only occurs when the resume code is successively run (more than one, without another yield). Any other error I get is: "attempt to call a string value". The pop code: if (lua_isstring(cL, -1)) { printf("isstring: %s\n", lua_tostring(cL, -1)); lua_pop(cL, -1); } –  dcousens  Aug 27 '11 at 13:35 
 
"attempt to call a string" means something else is on the stack other than your routine, possibly an error message. And when resume finishes with a return 0, the routine is done and you can't resume it any more, it's no longer on the stack. You can only resume again if you got a yield last time or pushed a new routine on the stack. –  BMitch  Aug 27 '11 at 17:23
 
How can I get the error message, if not through the code above? –  dcousens  Aug 28 '11 at 15:51
1  
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH. luaL_loadfile(cL, "scripts/loop.lua"); It all works now...crys. Thank you! –  dcousens  Sep 1 '11 at 2:51
1  
@Daniel, you're welcome, still can't believe I didn't see that until now. –  BMitch  Sep 1 '11 at 2:54

Last time i was messing with Lua coroutines I ended with such code

const char *program =
"function hello()\n"
"  io.write(\"Hello world 1!\")\n"
"  io.write(\"Hello world 2!\")\n"
"  io.write(\"Hello world 3!\")\n"
"end\n"
"function hate()\n"
"  io.write(\"Hate world 1!\")\n"
"  io.write(\"Hate world 2!\")\n"
"  io.write(\"Hate world 3!\")\n"
"end\n";

const char raw_program[] = 
"function hello()\n"
"  io.write(\"Hello World!\")\n"
"end\n"
"\n"
"cos = {}\n"
"\n"
"for i = 0, 1000, 1 do\n"
"  cos[i] = coroutine.create(hello)\n"
"end\n"
"\n"
"for i = 0, 1000, 1 do\n"
"  coroutine.resume(cos[i])\n"
"end";

int _tmain(int argc, _TCHAR* argv[])
{
    lua_State *L = lua_open();
    lua_State *Lt[1000];
    global_State *g = G(L);

    printf("Lua memory usage after open: %d\n", g->totalbytes);

    luaL_openlibs(L);

    printf("Lua memory usage after openlibs: %d\n", g->totalbytes);

    lua_checkstack(L, 2048);

    printf("Lua memory usage after checkstack: %d\n", g->totalbytes);

    //lua_load(L, my_lua_Reader, (void *)program, "code");
    luaL_loadbuffer(L, program, strlen(program), "line");

    printf("Lua memory usage after loadbuffer: %d\n", g->totalbytes);

    int error = lua_pcall(L, 0, 0, 0);
    if (error) {
        fprintf(stderr, "%s", lua_tostring(L, -1));
        lua_pop(L, 1);
    }

    printf("Lua memory usage after pcall: %d\n", g->totalbytes);

    for (int i = 0; i < 1000; i++) {
        Lt[i] = lua_newthread(L);
        lua_getglobal(Lt[i], i % 2 ? "hello" : "hate");
    }

    printf("Lua memory usage after creating 1000 threads: %d\n", g->totalbytes);

    for (int i = 0; i < 1000; i++) {
        lua_resume(Lt[i], 0);
    }

    printf("Lua memory usage after running 1000 threads: %d\n", g->totalbytes);

    lua_close(L);

    return 0;
}

It seems you could not load file as coroutine? but use function instead And it should be selected to the top of the stack.

lua_getglobal(Lt[i], i % 2 ? "hello" : "hate");
answered  Aug 30 '11 at 15:57
yatagarasu
356 2 11
 
1  
No need to create the coroutine in the Lua script, the lua_newthread call does that in C/C++. I use it myself without any issues. –  BMitch  Aug 30 '11 at 16:29
 
Actually I don't load raw_program. I should cut it from my post. But yes I see. The problem is with resuming coroutine. not starting them. should read original post carefully –  yatagarasu  Aug 30 '11 at 21:08
 
Just saw that you're using lua_newthread in your example. But yeah, OP has issues after yielding the coroutine. –  BMitch  Aug 30 '11 at 21:22
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Lua co-routines 的相关文章

  • Lua:字符串中的换行符

    我一直在开发一个格式化程序 它将接受一个长字符串并将其格式化为一系列在特定字符限制内的单词处断开的行 例如 他吃面包每 8 个字符断开一次 将返回类似以下内容的内容 He eats the bread 这是因为 He eats 包含 7 个
  • docker 单元测试设置

    我想为我的产品设置一个单元测试环境 我有一个基于 Lua 中的 nginx 构建的 Web 应用程序 它使用 mysql 和 redis 我认为 docker 会对此很有帮助 尽管我是 docker 的新手 我的应用程序运行在 centos
  • lua多重赋值

    lua中是否有任何多重赋值的方法 使得右侧缺失的值不被视为nil 类似于 a b c 1 但得到 a 1 b 1 c 1 结果 很遗憾 a b c 1 不起作用 我需要这个 因为我可能在右侧有复杂的表格 并且我想保持它简短 没有任何附加变量
  • Lua解释器相当于Matlab“whos”命令吗?

    Octave Matlab IPython whos 命令的 Lua 等价物是什么 我正在尝试以交互方式学习 Lua 并想看看当前定义了哪些变量 Lua 中的所有全局变量都驻留在可用作全局变量的表中 G http www lua org m
  • 如何在表格内打印表格的内容? [路亚]

    我想做的只是在表中打印表的内容 例如 local stats table1 tTable1 data 1 tTable2 data2 2 tTable3 data3 3 我并不真正关心表 1 或所有表 而是关心数据变量中的信息 我怎样才能打
  • ESP8266 NodeMCU 堆内存不足

    我正在尝试通过从我的笔记本电脑发送 POST 使用 node js 来使用 ESP8266 01 来切换 LED 我现在遇到内存问题 因为每当我发送 POST 请求时 ESP 中使用的内存就会增加 而堆内存会减少 并且当没有剩余内存时它会崩
  • Lua中如何去除字符串中的空格?

    我想从 Lua 中的字符串中删除所有空格 这是我尝试过的 string gsub str string gsub str string gsub str s 这似乎不起作用 如何删除所有空格 它有效 您只需分配实际结果 返回值 使用以下变体
  • 无法在cmake中使用find_package找到Lua标头

    我正在尝试使用 CMake 为我使用 Lua 的项目构建生成 make 文件 当我运行 make 时出现此错误 path to my project luaudio luaudio c 1 17 fatal error lua h No s
  • Lua:C++模块无法互相引用,未定义的符号

    我创建了两个模块 共享对象 CPU 和 SaveState 作为模拟器的一部分 两者都独立编译成 so 单独文件 并在运行时由 Lua 脚本使用 require 加载 IE SaveState require SaveState CPU r
  • 如何加载目录中的所有文件?

    正如标题所说 如何加载目录中的每个文件 我对c 和lua都感兴趣 编辑 对于 Windows 我很高兴能得到一些真正的工作代码 尤其是 lua 我可以用 boost filesystem for c 来做 对于 Lua 你需要模块Lua文件
  • Lua:“拖动”数组中的元素序列

    我正在尝试创建一个函数 将连续数量的元素 拖动 到数组中的新位置 并限制为数组的当前大小 其他项目应该围绕 拖动 的项目晃动 例如 如果我的数组有 7 个元素 并且我想拖动中间的三个 1 2 3 4 5 6 7 lt keys a b C
  • 如何使用Lua脚本语言打开Web套接字?

    作为初学者 我想在基于 Linux 的服务器上使用 Lua 打开一个 Web 套接字 该服务器应允许 Android 客户端连接到它 你能给我一些用Lua打开网络套接字的示例代码吗 您两周前已经问过同样的问题并得到了回答 LUA 脚本 We
  • 在 lua 中使用相等运算符比较数字有多安全?

    在我的引擎中 我有一个用于脚本编写的 Lua VM 在脚本中 我写了这样的内容 stage stage 1 if stage 5 then end and objnum tonumber 5 if stage objnum 根据 Lua 来
  • 如何访问废弃的函数参数?

    在 Lua 中 调用带有多余参数的函数将简单地丢弃这些参数 有没有可能与debug库来访问这些被丢弃的参数 我不是在寻找可变参数函数 function test local info debug getinfo 1 u print info
  • Lua中如何获取目录列表

    我需要 LUA 中的目录列表 假设我的目录路径为 C Program Files 我需要该特定路径中所有文件夹的列表以及如何搜索该列表中的任何特定文件夹 Example 需要路径 C Program Files 中所有文件夹的列表 以下是上
  • Lua中如何对数字表求和?

    Lua有内置的吗sum 功能 我似乎找不到一个 我几乎翻遍了文档中的所有地方 或许table sum 或类似的东西 以遵循当前的约定 但由于我找不到它 我不得不实现它 function sum t local sum 0 for k v i
  • 我应该用 C++ 封装 Lua 代码的哪些代码?

    我终于将 LuaBind 配置为与我的 C 项目一起使用 我最近发现 Tiled 地图编辑器可以选择将文件导出为 lua 所以我想尝试一下 我将使用什么代码来封装下面粘贴的代码以使其与我的 C RPG 项目一起使用 return versi
  • corona sdk中拖动物理对象

    我尝试在场景中拖动重力 0 0 的动态主体 我有一个主体类型为动态的正方形 以及一个主体类型为静态的图像 但是当将方形拖动到图像上时 它会产生一点力 但是可以超出图像并传递到另一边 如图所示 这是我拖动正方形的代码 local functi
  • 确定已编译Lua的编译器版本

    我有一些已编译的 LuaQ 我需要确定用于编译它的确切版本 有什么可能的方法吗 编译的脚本在文件开头有一个标头 4 bytes signature x1bLua 1 byte version 0x51 1 byte format 1 byt
  • 检查多个位置的值并仅在源唯一时返回匹配项

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

随机推荐

  • 【Basis】变分推断以及VIEM

    在包含隐变量 latent variables 的推断问题中 针对连续性随机变量的情况 隐变量的高维以及被积函数 intergrand 的复杂度使积分 intergration 无法进行 而针对离散型随机变量 隐变量呈指数 exponent
  • Git 本地代码上传到远程仓库

    Git本地代码上传到远程仓库 1 进入项目地址 通过命令git init将项目初始化成git本地仓库 git init 2 将项目内所有文件都添加到暂存区 git add 3 该命令会将git add 存入暂存区修改内容提交至本地仓库中 若
  • 寒假:HTML

    gt 框架的主要作用是使页面中的部分内容实现框架实现 一般用于在页面中引用站外的页面内容 1 在被打开的框架上加name属性 代码如下 2 在超链接上设置target目标窗口属性为希望显示的框架窗口名 lt a href target ma
  • dbeaver无法修改表数据_解决MDL锁导致无法操作数据库表的问题

    背景信息 MYSQL的MDL锁 用于解决或者保证DDL操作与DML操作之间的一致性 但是在部分场景下会出现阻塞 例如执行DML操作时执行ALTER操作 存在长时间查询时执行ALTER操作等等 表象如下 出现 Waiting for tabl
  • STM32 电机教程 20 - 基于ST MC Workbench 无感FOC

    前言 磁场定向控制又称矢量控制 FOC 本质上为控制定子电流的幅度和相位 使之产生的磁场和转子的磁场正交 以产生最大的扭矩 PMSM的磁场定向控制框图如下图所示 第19讲成功实现了基于NUCLEO F103RB和X NUCLEO IHM07
  • 计算几何学

    问题描述 对于线段s1 s2 如果相交则输出 1 否则输出 0 设s1的端点为p0 p1 s2的端点为p2 p3 输入 第1行输入问题数q 接下来q行给出q个问题 各问题线段s1 s2的坐标按照以下格式给出 x p 0 x p0
  • final关键字的继承问题

    final关键字的继承问题 前言 接口中的final关键字 基本接口 内部接口 接口中使用final有什么影响 抽象类中的final关键字 普通类中的final关键字 更多一点思考 前言 虽然现在已经有很多博客验证了final关键字的继承问
  • Linux 设备树的加载与匹配

    之前学习了platform设备与总线是如何匹配的 但是在读某一驱动程序中 该设备由dts文件描述 设备的匹配与platform设有所不同 因此记录下来 1 什么是设备树 在内核源码中存在大量对板级细节信息描述的代码 但是对于内核而言 这些代
  • Java设计模式——中介者模式

    文章目录 中介者模式 Demo 中介者模式与观察者模式区别 中介者模式 中介者模式也是用来降低类类之间的耦合的 因为如果类类之间有依赖关系的话 不利于功能的拓展和维护 因为只要修改一个对象 其它关联的对象都得进行修改 如果使用中介者模式 只
  • 多用户远程桌面服务器安装,Windows 2012 R2 多用户远程连接,只需三步骤

    Windows Server 2012默认情况下 只能提供两个用户远程桌面登陆 而通过安装远程桌面服务里的远程桌面会话主机和远程桌面授权 并设置组策略和注册表 即可实现多用户远程登录 第三个用户登录提示截图 注 默认情况下一个用户只能登录一
  • 企业微信配置小程序

    准备 1 注册企业微信服务商 地址 https open work weixin qq com wwopen developer index 2 开发好的小程序 已发布的 企业微信仅可关联已在微信小程序平台审核并发布的小程序 所关联的小程序
  • vue项目封装公共方法utils

    使用了很多个公共方法的封装方式以后 发现这个是我最喜欢的 也是用起来最顺手的 1 建立公共方法utils js export default test return test test1 return test1 2 挂载在main js
  • “我们无法设置移动热点” 解决方案

    win10中要开启热点时可能会报这个错 解决方法如下 1 右击电脑选择属性 设备管理器 2 选择网络适配器 下的WiFi模块 不同电脑名称会有差异 但是名字一定包含 wireless 双击它 选择高级设置 将2 4G 和 5 2G的信道宽度
  • MATLAB三维绘图(五)高级三维绘图

    MATLAB三维绘图 五 高级三维绘图 1 colorbar查看三维绘图中的内建颜色表 示例 画三维图 clear clc close all x y meshgrid 3 2 3 3 2 3 生成网格 z x 2 x y y 2 z的表达
  • uniapp checkbox radio 样式修改

    文章目录 通过查看代码 发现 before部分是设置样式的主要属性 我们要设置的话 就要设置checkbox before的属性 其中的content表示内容 比如内部的对勾 那么我们设置的时候 比如设置disable true的时候或者c
  • Makefile中的-C和M=解析

    转载地址 https www aliyun com jiaocheng 144874 html 当make的目标为all时 C KDIR 指明跳转到内核源码目录下读取那里的Makefile M PWD 表明然后返回到当前目录继续读入 执行当
  • Wireshark抓包解释说明

    Wireshark与对应的OSI七层模型 TCP三次握手 TCP三次握手的理论知识 wireshark三次握手对应的报文情况 图中可以看到wireshark截获到了三次握手的三个数据包 第四个包才是HTTP的 这说明HTTP的确是使用TCP
  • hive解决数据倾斜之寻找大key

    参考文献 执行hive sql时 如果某个reduce任务特别慢 很可能是出现了数据倾斜 如何查找数据倾斜 第一步 在hive日志里找到当前job的日志 第二步 查看counter 点击进入 reduce input records 发现有
  • python matplotlib在图像上指定位置加框的一些心得(深度学习图像标注可视化经常面临的问题)

    matplotlib显示图像 显示图像需要配合PIL库 python中pillow库 导入matplotlib pyplot库 导入matplotlib patches库 picdir是图片的路径 直接采用Image open picdir
  • Lua co-routines

    Lua co routines up vote 7 down vote favorite 1 http stackoverflow com questions 7206411 lua co routines I m trying to ge