如果不在光纤中调用产量会怎样?

时间:2016-04-21 07:28:48

标签: multithreading d yield coroutine fibers

据我理解yield(),函数将控制传递给另一根光纤。 如果我们不在D中称光纤产量会怎样?这是否意味着线程会挂起?

或者我错了理解纤维在线程内部工作并且它们在内部工作?流程可以有threadsfibers

2 个答案:

答案 0 :(得分:5)

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

当光纤功能结束时,它只是将控制权返回给最后一个呼叫者,就像最后一次呼叫yield一样。主要区别在于,当光纤功能结束时,匹配的光纤对象进入“终止”状态,并且在产生时它总是保持在“运行”状态(即使没有更多的技术运行)。这很重要,因为它只定义了在终止状态下重置和回收光纤的行为。

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

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

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);
}

答案 1 :(得分:1)

如果您的光纤功能永远不会yield() s,那么它就不合作,这意味着一旦执行进入该功能,其他光纤将无法完成其工作。