3

正如我从文档中了解到的那样,yield()功能是将控制权传递给另一根光纤。如果我们不在 D 中调用纤维中的产量会发生什么?这是否意味着线程会挂起?

或者我错误地理解纤维在线程内部工作并且它们在进程内部工作?过程可以有 orthreadsfibers?

4

2 回答 2

5

要回答这个问题,了解纤维的工作原理很重要。当您调用Fiber.call()方法时,当前执行上下文(CPU 寄存器状态)被转储到内存中,并加载该纤程对象的执行上下文。当您调用Fiber.yield()当前执行上下文时,也会转储,但控制权会传递给上次调用当前纤程的人。它既可以是另一个纤程上下文,也可以是普通线程上下文——它不需要知道,因为任何执行上下文都完全由转储数据定义,它甚至不需要知道纤程。

当 Fiber 函数结束时,它只是将控制权返回给最后一个调用者,就像最后有一个yield调用一样。主要区别在于,当 Fiber 功能结束时,匹配的 Fiber 对象进入“终止”状态,并且在屈服时它始终保持在“运行”状态(即使在技术上不再运行)。这很重要,因为它只是在终止状态下重置和回收光纤的定义行为。

常见的错误是将纤程视为某种任务并期望固有的调度语义。事实并非如此——光纤本身只是一个上下文切换原语,可以在上面实现任何智能任务系统,它自己从来没有任何调度。

一些显示相关语义的代码示例:

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);
}
于 2016-04-21T17:13:10.210 回答
1

如果你的 fiber-function 从来没有yield()s,那么它就不是合作的,这意味着一旦执行进入那个函数,其他的 Fiber 就不会完成它们的工作。

于 2016-04-21T14:22:42.107 回答