【发布时间】:2017-07-02 14:07:23
【问题描述】:
这在之前已经讨论过了,所有可以从外部做的似乎就是杀死协程。这对于调度程序当然是不切实际的。有没有办法从外部暂停协程或解决方法?
【问题讨论】:
这在之前已经讨论过了,所有可以从外部做的似乎就是杀死协程。这对于调度程序当然是不切实际的。有没有办法从外部暂停协程或解决方法?
【问题讨论】:
从 C API,您可以在 $n 行/指令之后产生 set a hook。 (这通过debug.sethook 是不可能的,因为它添加了一个中间层来阻止它工作。)
你可以把它封装成一个可以暴露给 Lua 的函数,所以除了添加那个函数之外,你还可以从 Lua 中完成。示例:
static int setyieldhook( lua_State * L ) {
lua_State * coro;
int steps;
luaL_checktype( L, 1, LUA_TTHREAD );
coro = lua_tothread( L, 1 );
steps = luaL_optinteger( L, 2, 0 );
if (steps <= 0) {
lua_sethook( coro, NULL, 0, 0 );
} else {
lua_sethook( coro, yieldhook, LUA_MASKCOUNT, steps );
}
return 0;
}
然后将其作为函数推送到 Lua 并为其命名,例如debug.setyieldhook.
这个将被用作debug.setyieldhook( coro, timeout ) 并且每当协程运行时,它将在timeout Lua 指令之后产生。要清除,debug.setyieldhook( coro, 0 )。 (注意:您不能更改/删除通过setyieldhook 到debug.sethook 设置的钩子,反之亦然——这将引发错误或默默地造成混乱。但您可以扩展setyieldhook 以检测和清除“正常” Lua 钩子,和/或包装 debug.sethook 以检查并清除 yield 钩子。)
其他需要注意的事项:
yields,这不会重置挂钩计时器。coroutine.yield 和/或coroutine.resume 这样你就可以区分
“正常”yields 来自超时 yields。string.*),所以这不提供硬性时序保证。【讨论】:
yield。 (所以你实际上是在模拟一个操作系统,比方说,所有io、os、...函数can如果时间到了。)或者也许(没试过这个一)设置一个具有任意超时条件的普通钩子,它只用带有__index/__newindex的虚拟表替换全局环境或一些经常访问的东西。当元方法触发时,它会将其更改回正常事物,让步,然后(在恢复后)对正常事物重新执行劫持操作。