Lua 中的多线程

我和我的朋友最近在讨论一个话题。我说在纯 Lua 中无法建立一个抢先多任务系统,但他否认了这一点。他的理由是:

C 和 Lua 都没有内置的线程库[OP注意: 实际上 Lua 有,但据我所知对于我们的目的来说没有什么用]。Windows 几乎完全是 C++ 写成的,它有抢先多任务,是从头开发的。因此,你应该能在 Lua 中做到同样的事情。

我看到的一个大问题是,我了解到抢先多任务的主要工作方式是生成定期的中断,经理使用这些中断获得控制权,并确定它应该处理哪个代码。我也不认为 Lua 有任何可以做到这一点的功能。

我的问题是: 是否有可能编写一个纯 Lua 库,让人们可以使用抢先多任务?

原文链接 https://stackoverflow.com/questions/2978120

点赞
stackoverflow用户159876
stackoverflow用户159876

我不知道,没有办法通过debug.sethook设置的钩子来从协程中产生返回,这几乎太简单了,所以不起作用。你可以从由C(lua_sethook)设置的C钩子中跳出,但我无法确定应该如何执行,并且它本身就不是纯Lua。

即使可能性存在,它也不是真正的线程。例如,所有内容仍将在同一个操作系统线程中运行。您的钩子将考虑各种因素(如时间、内存等),然后确定是否应产生返回。然后,产生返回的协程将决定下一个要运行的子协程。您还需要决定何时调用钩子。最频繁的是在每个Lua指令上,但这会带来性能损失。如果协程调用C函数,Lua无权干涉。如果该C调用需要很长时间,您将无能为力。

这里有一个相关的Lua-L邮件列表主题,您可能会发现它很有趣。

2010-06-05 04:00:45
stackoverflow用户41661
stackoverflow用户41661

我无法想象如何做到这一点,尽管没有像yield语义这样的Lua正式语义,很难提出一种无法完成的论据。 (我一直渴望一个正式的语义已经许久了,但显然Roberto和lhf有更好的事情要做。)

如果我想让Lua支持抢占式多任务处理,我甚至都不会尝试用纯Lua来完成。相反,我会使用20年前在New Jersey标准ML中第一次看到的一个古老技巧:

  • 中断在lua_State中设置一个标志,表示“当前协程已被抢占”。

  • 修改虚拟机,使得在每个循环和每个函数调用时,它都会检查标志是否需要进行抢占。

这个补丁很容易编写和维护。它并不解决无法抢占的长时间运行的C函数的问题,但如果您必须解决这个问题,那么您正在踏入比较困难的领域,您可能会在C级别而不是Lua级别上处理所有线程。

2010-06-05 14:19:57
stackoverflow用户1201125
stackoverflow用户1201125

不,纯 Lua 中不可能编写出抢占式调度器。抢占式调度器在某个时间点需要一些机制,比如中断服务例程,来控制当前线程并将其切换给调度器,然后再切换给另一个线程。而纯 Lua 并没有这样的机制。

你提到 Windows 大部分用 C/C++ 编写。但关键是“大部分”。你不能在纯 ANSI C/C++ 中编写抢占式调度器。通常,部分中断服务例程是用汇编语言编写的。或者,C/C++ 编译器实现了一种非标准扩展,允许使用 C/C++ 编写中断服务例程。一些编译器可以声明一个带有“__interrupt”修饰符的函数,导致编译器生成一个允许该函数用作中断服务例程的延长/前奏的代码。

此外,设置中断服务例程的代码要用到 CPU 寄存器和内存映射 I/O 或 I/O 指令,这些代码都不是 ANSI C/C++ 可移植的。并且,这些代码依赖特定的 CPU 架构。

2012-02-10 02:48:51