Lua协同例程
Lua co-routines
我正试图了解如何使用协同例程来"暂停"脚本,并等待一些处理完成后再恢复。
也许我以错误的方式看待协同例程。但我的尝试结构类似于这个答案中给出的例子。
loop.lua
中的循环从未达到第二次迭代,因此从未达到C代码中退出运行循环所需的i == 4
条件。如果我在loop.lua
中没有屈服,则此代码按预期执行。
main.cpp
#include <lua/lua.hpp>
bool running = true;
int lua_finish(lua_State *) {
running = false;
printf("lua_finish calledn");
return 0;
}
int lua_sleep(lua_State *L) {
printf("lua_sleep calledn");
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 yieldingn");
} 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: %sn", 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()
编辑:添加了一个赏金,希望能得到一些关于如何完成这个任务的帮助。
lua_resume
返回代码2为LUA_ERRRUN
。检查Lua堆栈顶部的字符串以查找错误消息。
一个类似的模式已经为我工作,虽然我确实使用coroutine.yield
而不是lua_yield
,我在C而不是c++。我不明白为什么你的解决办法行不通
在你的简历电话中,我不清楚你是否过度简化了一个例子,但我会在你的while循环中做以下改变:
int status;
status=lua_resume(cL,0);
if (status == LUA_YIELD) {
printf("loop yieldingn");
}
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: %sn", lua_tostring(cL, -1));
lua_pop(cL, -1);
}
}
编辑2:要进行调试,请在运行简历之前添加以下内容。你有一个字符串被压入堆栈的某个地方:
int status;
// add this debugging code
if (lua_isstring(cL, -1)) {
printf("string on stack: %sn", lua_tostring(cL, -1));
exit(1);
}
status = lua_resume(cL,0);
编辑3:哦,好悲伤,我不敢相信我没有看到这个,你不想运行luaL_dofile
当你要屈服的时候,因为你不能直接屈服pcall据我所知,这是在dofile中发生的事情(5.2将传递它,但我认为你仍然需要lua_resume)。切换到这个:
luaL_loadfile(cL, "scripts/loop.lua");
上次我摆弄Lua协程时,我写了这样的代码
const char *program =
"function hello()n"
" io.write("Hello world 1!")n"
" io.write("Hello world 2!")n"
" io.write("Hello world 3!")n"
"endn"
"function hate()n"
" io.write("Hate world 1!")n"
" io.write("Hate world 2!")n"
" io.write("Hate world 3!")n"
"endn";
const char raw_program[] =
"function hello()n"
" io.write("Hello World!")n"
"endn"
"n"
"cos = {}n"
"n"
"for i = 0, 1000, 1 don"
" cos[i] = coroutine.create(hello)n"
"endn"
"n"
"for i = 0, 1000, 1 don"
" 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: %dn", g->totalbytes);
luaL_openlibs(L);
printf("Lua memory usage after openlibs: %dn", g->totalbytes);
lua_checkstack(L, 2048);
printf("Lua memory usage after checkstack: %dn", g->totalbytes);
//lua_load(L, my_lua_Reader, (void *)program, "code");
luaL_loadbuffer(L, program, strlen(program), "line");
printf("Lua memory usage after loadbuffer: %dn", 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: %dn", 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: %dn", g->totalbytes);
for (int i = 0; i < 1000; i++) {
lua_resume(Lt[i], 0);
}
printf("Lua memory usage after running 1000 threads: %dn", g->totalbytes);
lua_close(L);
return 0;
}
似乎你不能加载文件作为协程?但是用function代替,它应该被选择到堆栈的顶部。
lua_getglobal(Lt[i], i % 2 ? "hello" : "hate");
相关文章:
- 尝试通过OCI例程从Oracle获取blob数据,但出现错误:ORA-01008:并非所有变量都绑定
- c++类声明时,相同的例程,不同的成员变量类型
- C++为线程工作动态地分割例程
- 子例程,不使用 pow,并带有参数和返回
- 直接在RcppArmadillo中调用LAPACK例程
- 如何将C++子例程链接到 x86 程序集程序?
- PX 转换例程编译问题
- 成功完成TLS握手后,服务器关闭时出现错误的SSL例程:SSL3_GET_RECORD:错误的版本号
- 只允许授权代码调用库中的例程
- JNI 不满意链接错误: 动态链接库 (DLL) 初始化例程失败
- 调用子例程时类型不匹配
- 将分配给C++数组传递给 Fortran 子例程
- Android Studio 3.1.2 - 无法运行C++子例程"No implementation found for Java.lang.String..."
- Posix 线程类和启动例程 (pthread)
- OpenBLAS 只为一个例程设置线程数
- 检查并行化 BLAS 例程的结果
- 我们应该测量例程的平均执行时间还是最小执行时间?
- 试图在C 中调用Fortran子例程
- C++ 我的函数在我的 Image 类中工作,但不在主例程中工作
- Lua协同例程