从不同的纤程调用需要主线程的函数

Call functions that require the main thread from different fibers

有很多函数应该从主线程调用。以我有限的经验,这些主要是 UI 函数。

示例:

假设我有一个 fiber 库,它创建 "threads" 和 set/get 上下文。从主 OS 线程启动的任何纤程调用仅主线程函数是否安全?

我认为这很好,因为 OS 不知道我的光纤,但我不确定。我会对此进行测试,但结果不会是确定的,因为它可能有效但依赖于未定义的行为。

编辑:将此问题标记为 C,因为 set/get 上下文是 C 函数,尽管如评论中所述,我认为它也可能适用于用其他语言编写的程序。

是的,您可以从任何上下文调用程序中的任何函数。请注意,使用 getcontextsetcontext 并不能使 "threads" 成为现实,并且您不会得到任何并行处理 - 您只会得到调度。这就是它会起作用的原因,无论它是否是 UI 函数。它基本上只是一个跨功能的 goto。直接引用manpage

If the context was obtained by a call of getcontext(), program execution continues as if this call just returned.

这意味着如果我写

... code ... getcontext(&cxt); ... code ... setcontext(&cxt);

然后当我到达setcontext时,我进入的状态与函数getcontext刚返回时相同。没有明显的区别(当然,您可能同时更改了内存值,但这不是重点)。联机帮助页与 makecontext 有类似的保证,但请注意它会在给定函数完成执行后重定向您。

你给出的例子是高级编程语言,复杂度高很多,不像C中的setcontext/getcontext那么简单。您发布的 Java 错误似乎实际上是一个不同的 OS 线程,与第三个示例相同。第一个示例看起来可能是一个假线程,但当然有隐藏的复杂性可能会阻止 UI 调用工作(因为它们与外部 API 交互)。

这就是为什么在 JS 中使用线程如此简单:因为线程不是真实的。你在并行性能上失去的东西,你获得的是能够从你的分派函数和 ajax 调用中的任何地方调用任何东西。

如果您知道您的纤程库实际上只使用 getcontextsetcontext,那么您会没事的。不过图书馆可能会做其他事情,所以在这种情况下最好与图书馆作者核实一下。