gpt4 book ai didi

你能在 C 的任何地方 Yield 和 Resume Luajit 协程吗?

转载 作者:太空狗 更新时间:2023-10-29 15:05:23 26 4
gpt4 key购买 nike

我正在尝试提出一种解决方案,用于从 C 函数生成 Luajit 协程,该函数立即创建一个 tasklet 以在另一个操作系统线程上进行处理。

根据各种 Lua 文档,事情开始相互严重矛盾,这不是完全可能的吗?文档不是很清楚,也没有解释原因。

Lua 5.1 规定每个协程都有一个堆栈。但是,只有一个全局 C 堆栈。我不完全确定为什么这是一个障碍。

Lua 5.2 显然用 lua_pcallk 和 lua_yieldk 修复了这个问题。但是解释非常困惑。

但这些都没有说明我正在使用的 VM...即 LuaJIT 2.0.4 和 LuaJIT 2.1.0。

谷歌搜索告诉我 Luajit 1.x 实现了 CoCo,它显然为每个 lua 线程(协程)使用了真正的 C 堆栈。这允许从任何地方屈服。

只有一次搜索让我看到 LuaJIT 2.x 显然没有实现 coco,因为每个协程都使用 C 堆栈。

谁能告诉我从 C 生成协程的问题是什么?并验证我是否可以从 c 安全地产生/恢复 luajit 2.x 协程?

最佳答案

在引用Lua实现中,每个Lua协程都有自己的Lua栈,它只是lua_State中的一个数组,与C栈无关。 Lua 无法保存 C 堆栈(因为这在标准 C 中是不可能的),因此如果当前正在执行 C 函数,则它无法生成协程。

例如,如果您有 Lua 函数 a 调用 C 函数 b 调用 Lua 函数 c,并且 c 尝试让步,Lua 将无法保存 b 的局部变量(因为它是 C 函数)并且会失败。

这也适用于很多内置的 Lua 函数。正如您提到的,在 Lua 5.1 中,实现不支持在 pcall 中产生,直到 Lua 5.2 显然添加了特殊函数以使其工作。

Coco 是标准 Lua 实现的补丁,它在协程中实现了单独的 C 堆栈,因此 Lua 现在可以“保存”C 函数变量。显然 LuaJit 1.x 也包含它。它不适用于 LuaJit 2.x,因为它是 Lua 的完全不同的实现。


LuaJit 2.x 在 Extensions page 中有以下段落:

Fully Resumable VM

The LuaJIT VM is fully resumable. This means you can yield from a coroutine even across contexts, where this would not possible with the standard Lua 5.1 VM: e.g. you can yield across pcall() and xpcall(), across iterators and across metamethods.

显然,跨内置函数的 yield 应该可以工作,尽管它是否适用于任意 Lua C API 函数仍然是模棱两可的。然而,它很容易测试;编写一个简单的 C API 函数,它接受一个 Lua 函数并调用它,然后将一个函数传递给它,该函数会产生。如果它不起作用,它应该抛出一个错误。

请注意,使用 FFI 加载的普通 C 函数根本不允许触及 Lua 状态。。这包括尝试屈服。

关于你能在 C 的任何地方 Yield 和 Resume Luajit 协程吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40682722/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com