我知道使用协程作为基础和实现玩具调度程序的基础知识。但我认为这是对整个异步调度程序的过度简化的看法。我的想法中缺少一整套漏洞。
如何防止 CPU 运行空闲/等待的调度程序?一些纤程只是休眠,另一些则等待操作系统的输入。
我知道使用协程作为基础和实现玩具调度程序的基础知识。但我认为这是对整个异步调度程序的过度简化的看法。我的想法中缺少一整套漏洞。
如何防止 CPU 运行空闲/等待的调度程序?一些纤程只是休眠,另一些则等待操作系统的输入。
您需要将 io 操作多路复用到基于事件的接口(选择/轮询)中,因此您可以利用操作系统进行等待,同时仍然能够安排其他纤程。select/poll 有一个超时参数——对于想要休眠的纤程,您可以创建一个优先级队列,该队列使用 select/poll 的选项来模拟休眠调用。
尝试为执行阻塞操作(调用读/写/睡眠等)的纤程提供服务。除非您将每个光纤安排在本机线程中,否则直接将无法正常工作-哪种方式超出了目的。
有关工作实施,请参阅http://swtch.com/libtask/ 。
您可能应该看看 setcontext 系列函数 ( http://en.wikipedia.org/wiki/Setcontext )。这意味着在您的应用程序中,您需要将所有可能阻塞(读取、写入、睡眠等)的函数重新实现为异步形式并返回到调度程序。
只有“调度器纤程”才能使用 select()、poll() 或 epoll() 等待完成事件。这意味着当调度程序空闲时,进程将在 select/poll/epoll 调用中处于休眠状态,并且不会占用 CPU。
虽然回答有点晚了,但我想提一下,我在 C 语言中有一个纤程库的实际实现,称为libevfibers。
尽管是一个年轻的项目,但它已用于生产。它不仅为读/写套接字等经典异步操作提供了解决方案,而且还以非阻塞方式处理文件系统 IO。该项目利用了 3 个很棒的库——libcoro、libev 和 libeio。
您也可以通过使用协程来控制控制流。支持创建这些的库是 BOOST.ASIO。
这里有一个很好的例子:Boost Stackful Coroutines
从实现的角度来看,您可以从异步事件循环实现开始。然后,您可以通过使用异步事件处理程序切换到相应的光纤来实现光纤调度。
睡眠/等待光纤只是意味着它目前没有被安排 - 它只是切换到事件循环。
顺便说一句,如果您正在寻找一些实际代码,请查看http://svn.cmeerw.net/src/nginetd/trunk/仍在进行中,但尝试在多线程事件循环(使用 Win32 I/O 完成端口或 Linux 边缘)之上实现光纤调度程序-触发的epoll)。