9

前几天我正在和我的朋友讨论。我说的是,在纯 Lua 中,你无法构建一个抢占式多任务系统。他声称你可以,原因如下:

C 和 Lua 都没有内置的线程库 [OP 的注释:嗯,Lua 在技术上是有的,但 AFAIK 它对我们的目的没有用]。主要用 C(++) 编写的 Windows 具有先发制人的多任务处理能力,这是他们从头开始构建的。因此,您应该能够在 Lua 中做同样的事情。我看到的一个大问题是抢占式多任务处理的主要工作方式(据我所知)是它会生成定期中断,管理器使用这些中断来获得控制并确定接下来应该处理哪些代码。我也不认为 Lua 有任何设施可以做到这一点。

我的问题是:是否可以编写一个纯 Lua 库,让人们可以进行抢先式多任务处理?

4

3 回答 3

9

我不知道该怎么做,虽然没有 Lua 的正式语义(例如语义yield),但很难想出一个铁定的论据为什么它不能完成。(多年来,我一直想要一个正式的语义,但显然 Roberto 和lhf有更好的事情要做。)

如果我想要 Lua 的抢先式多任务处理,我什至不会尝试在纯 Lua 中实现。相反,我会使用 20 年前在新泽西标准 ML 中第一次看到的旧技巧:

  • 中断在lua_State“当前协程已被抢占”的说法中设置了一个标志。

  • 更改 VM,以便在每个循环和每个函数调用中,它都会检查标志并在必要时生成。

这个补丁很容易编写和维护。它并没有解决无法被抢占的长时间运行的 C 函数的问题,但是如果你必须解决这个问题,你就会陷入更难的领域,你不妨在C 级别,而不是 Lua 级别。

于 2010-06-05T14:19:57.590 回答
6

不,不可能用纯 Lua 编写抢占式调度程序。在某些时候,抢占式调度程序需要某种机制,例如中断服务例程,以从当前线程中获取控制权并将其交给调度程序,然后调度程序可以将其交给另一个线程。纯 Lua 没有这种机制。

You mention that Windows is written in mostly C/C++. The keyword is mostly. You can't write a preemptive scheduler in pure ANSI C/C++. Usually, part of the interrupt service routine is written in assembly language. Or, the C/C++ compiler implements a non-standard extension that allows interrupt service routines to be written in C/C++. Some compilers allow you to declare a functions with an __interrupt modifier that that causes the compiler to generate a prolong / epilog that allows the function to be used as an interrupt service routine.

Also, code that sets up the interrupt service routine fiddles with CPU registers with memory mapped IO, or a IO instructions. None of this code is portable ANSI C/C++. And, depends on the CPU architecture.

于 2012-02-10T02:48:51.460 回答
5

不是我知道的,不。如果你可以使用 debug.sethook 从协程上设置的钩子中产生,这几乎是荒谬的简单,但它不起作用。您可以从 C (lua_sethook) 设置的 C 钩子中产生,但我无法确切地做到这一点,而且它也不是纯粹的 Lua。

即使有可能,它也不是真正的线程。例如,一切仍将在同一个操作系统线程中运行。你的钩子会考虑多种因素(比如时间,也许是内存等),然后决定是否让步。然后,yield-to 协程将决定接下来运行哪个子协程。您还需要决定何时调用钩子。最常见的是每条 Lua 指令,但这会带来性能损失。而如果协程调用了一个 C 函数,Lua 没有管辖权。如果该 C 调用需要很长时间,那么您无能为力。

是来自 Lua-L 邮件列表的相关主题,您可能会觉得有趣。

于 2010-06-05T04:00:45.870 回答