代码之家  ›  专栏  ›  技术社区  ›  Cheery

如何实现一个实用的光纤调度程序?

  •  9
  • Cheery  · 技术社区  · 17 年前

    我非常了解使用协程作为基础和实现玩具调度程序的基本知识。但我认为这是关于异步调度程序的过于简单化的观点。在我的思想中,有一整套的洞不见了。

    如何防止CPU运行空闲/等待的调度程序?有些光纤只是休眠,另一些则等待操作系统的输入。

    5 回复  |  直到 11 年前
        1
  •  7
  •   nos    16 年前

    您需要将IO操作多路复用到一个基于事件的接口(select/poll),这样您就可以利用操作系统来完成等待,同时还可以调度其他光纤。select/poll有一个超时参数-对于要休眠的光纤,可以创建一个优先级队列,该队列使用select/poll选项模拟休眠调用。

    尝试为执行阻塞操作(调用读/写/睡眠等)的光纤提供服务。除非您在一个本机线程中调度每个光纤,否则直接将无法工作—哪种方式会超过目的。

    http://swtch.com/libtask/ 用于有效的实现。

        2
  •  5
  •   Ho Ming Shun    17 年前

    您可能应该看看setContext函数系列( http://en.wikipedia.org/wiki/Setcontext )这意味着,在应用程序中,您需要重新实现所有可能阻塞(读、写、睡眠等)到异步表单并返回调度程序的函数。

    只有“调度程序光纤”才能使用select()、poll()或epoll()等待完成事件。这意味着当调度程序空闲时,进程将在select/poll/epoll调用中休眠,并且不会占用CPU。

        3
  •  1
  •   Lupus    11 年前

    虽然现在回答有点晚,但我想说的是,我在C语言中有一个光纤库的实际实现,叫做 libevfibers .

    尽管它是一个年轻的项目,但在生产中使用。它不仅为经典的异步操作(如读/写套接字)提供了解决方案,而且还以非阻塞方式处理文件系统IO。该项目利用了3个大型图书馆——libcoro、libev和libeio。

        4
  •  1
  •   schoetbi    11 年前

    您也可以通过协程控制控制流。一个支持这些创建的库是boost.asio。

    这里有一个很好的例子: Boost Stackful Coroutines

        5
  •  0
  •   cmeerw    17 年前

    从实现的角度来看,您可以从异步事件循环实现开始。然后,通过使用异步事件处理程序切换到相应的光纤,您可以在此基础上实现光纤调度。

    休眠/等待光纤只是意味着它现在没有被调度——它只是切换到事件循环。

    顺便说一句,如果您正在寻找一些实际的代码,请看一下 http://svn.cmeerw.net/src/nginetd/trunk/ 它仍在进行中,但尝试在多线程事件循环(使用Win32 I/O完成端口或Linux边缘触发的epoll)之上实现光纤调度程序。