有很多函数应该从主线程调用。以我有限的经验,这些主要是 UI 功能。
例子:
假设我有一个使用设置/获取上下文创建“线程”的光纤库。从主操作系统线程开始的任何光纤调用仅主线程函数是否安全?
我认为这很好,因为操作系统不知道我的纤维,但我不确定。我会对此进行测试,但结果不会是明确的,因为它可能有效但依赖于未定义的行为。
编辑:将此问题标记为 C,因为 set/get context 是 C 函数,尽管如评论中所述,我认为它也可能适用于用其他语言编写的程序。
有很多函数应该从主线程调用。以我有限的经验,这些主要是 UI 功能。
例子:
假设我有一个使用设置/获取上下文创建“线程”的光纤库。从主操作系统线程开始的任何光纤调用仅主线程函数是否安全?
我认为这很好,因为操作系统不知道我的纤维,但我不确定。我会对此进行测试,但结果不会是明确的,因为它可能有效但依赖于未定义的行为。
编辑:将此问题标记为 C,因为 set/get context 是 C 函数,尽管如评论中所述,我认为它也可能适用于用其他语言编写的程序。
是的,您可以从任何上下文调用程序中的任何函数。请注意,使用getcontext
andsetcontext
并没有创建真正的“线程”,并且您没有得到任何并行处理 - 您只是得到调度。这就是为什么它会起作用,无论它是否是 UI 功能。它基本上只是一个跨功能工作的 goto。直接引用手册页:
如果上下文是通过调用 getcontext() 获得的,则程序继续执行,就好像这个调用刚刚返回一样。
这意味着如果我写
... code ...
getcontext(&cxt);
... code ...
setcontext(&cxt);
然后当我到达时setcontext
,我去的状态与函数刚返回时的状态相同。getcontext
没有可察觉的差异(当然,您可能同时更改了内存值,但这无关紧要)。手册页具有与 类似的保证makecontext
,但请注意它会在给定函数完成执行后重定向您。
您提供的示例使用更高级别的编程语言,它们具有更多的复杂性,因此不像setcontext
/ getcontext
in那样简单C
。您发布的 Java 错误似乎实际上是一个不同的操作系统线程,与第三个示例相同。第一个示例看起来可能是一个假线程,但当然有隐藏的复杂性可能会阻止 UI 调用工作(因为它们与外部 API 交互)。
这就是为什么 JS 中的线程如此简单:因为线程不是真实的。你在并行性能中损失了什么,你可以从调度的函数和 ajax 调用中调用任何地方的任何东西。
如果您知道您的光纤库实际上只使用getcontext
and setcontext
,那么您会没事的。虽然图书馆可能会做其他事情,所以在这种情况下最好与图书馆作者核实。