如果不在 fiber 中调用 yield 会发生什么?
What will happen if not call yield in fiber?
据我从文档中了解到 yield()
函数正在将控制权传递给另一个光纤。
如果我们不在 D 中的 fiber 中调用 yield 会发生什么?这是否意味着线程会挂起?
或者我错误地理解纤维在线程内部工作并且它们在进程内部工作?进程可以有或 threads
或 fibers
?
如果你的fiber-function从不yield()
s,那么它是不合作的,这意味着一旦执行进入该函数,其他fibers将不会完成它们的工作。
要回答这个问题,了解纤维的工作原理很重要。当您调用 Fiber.call()
method, current execution context (CPU register state) gets dumped into memory and execution context for that fiber object is loaded instead. When you call Fiber.yield()
时,当前执行上下文也会被转储,但控制权将传递给上次调用当前纤程的任何人。它可以是另一个纤程或普通线程上下文——它不需要知道 any 执行上下文完全由转储数据定义,它甚至不需要纤程感知。
当 fiber 函数结束时,它只是 returns 控制最后一个调用者,就像最后有一个 yield
调用一样。主要区别在于,当 fiber 函数结束时,匹配的 fiber 对象进入 "terminated" 状态,并且在 yield 时它始终保持在 "running" 状态(即使在技术上没有更多的 运行 )。这很重要,因为它只是在终止状态下重置和回收纤程的定义行为。
常见的错误是将纤程视为某种任务并期望固有的调度语义。事实并非如此 - 光纤本身只是一个上下文切换原语,用于在顶部实现任何智能任务系统,它自己从来没有任何调度。
显示相关语义的一些代码示例:
void main ( )
{
import core.thread, std.stdio;
Fiber fiber1, fiber2;
fiber1 = new Fiber({
fiber2.call();
Fiber.yield();
});
fiber2 = new Fiber({
Fiber.yield();
});
fiber1.call(); // switches to fiber1, which switches to fiber2
// which yield back to fiber1 and finally fiber1 yield back to main
assert (fiber1.state == Fiber.State.HOLD && fiber2.state == Fiber.State.HOLD);
fiber2.call(); // switches to fiber2 which reaches end of function
// and switches back to main upon exit
assert (fiber1.state == Fiber.State.HOLD && fiber2.state == Fiber.State.TERM);
fiber1.call(); // switches to fiber1 which also reaches end of function
// and switches back to main upon exist
assert (fiber1.state == Fiber.State.TERM && fiber2.state == Fiber.State.TERM);
}
据我从文档中了解到 yield()
函数正在将控制权传递给另一个光纤。
如果我们不在 D 中的 fiber 中调用 yield 会发生什么?这是否意味着线程会挂起?
或者我错误地理解纤维在线程内部工作并且它们在进程内部工作?进程可以有或 threads
或 fibers
?
如果你的fiber-function从不yield()
s,那么它是不合作的,这意味着一旦执行进入该函数,其他fibers将不会完成它们的工作。
要回答这个问题,了解纤维的工作原理很重要。当您调用 Fiber.call()
method, current execution context (CPU register state) gets dumped into memory and execution context for that fiber object is loaded instead. When you call Fiber.yield()
时,当前执行上下文也会被转储,但控制权将传递给上次调用当前纤程的任何人。它可以是另一个纤程或普通线程上下文——它不需要知道 any 执行上下文完全由转储数据定义,它甚至不需要纤程感知。
当 fiber 函数结束时,它只是 returns 控制最后一个调用者,就像最后有一个 yield
调用一样。主要区别在于,当 fiber 函数结束时,匹配的 fiber 对象进入 "terminated" 状态,并且在 yield 时它始终保持在 "running" 状态(即使在技术上没有更多的 运行 )。这很重要,因为它只是在终止状态下重置和回收纤程的定义行为。
常见的错误是将纤程视为某种任务并期望固有的调度语义。事实并非如此 - 光纤本身只是一个上下文切换原语,用于在顶部实现任何智能任务系统,它自己从来没有任何调度。
显示相关语义的一些代码示例:
void main ( )
{
import core.thread, std.stdio;
Fiber fiber1, fiber2;
fiber1 = new Fiber({
fiber2.call();
Fiber.yield();
});
fiber2 = new Fiber({
Fiber.yield();
});
fiber1.call(); // switches to fiber1, which switches to fiber2
// which yield back to fiber1 and finally fiber1 yield back to main
assert (fiber1.state == Fiber.State.HOLD && fiber2.state == Fiber.State.HOLD);
fiber2.call(); // switches to fiber2 which reaches end of function
// and switches back to main upon exit
assert (fiber1.state == Fiber.State.HOLD && fiber2.state == Fiber.State.TERM);
fiber1.call(); // switches to fiber1 which also reaches end of function
// and switches back to main upon exist
assert (fiber1.state == Fiber.State.TERM && fiber2.state == Fiber.State.TERM);
}