操作系统如何在接受同一套接字的多个进程之间进行负载平衡?

我正在阅读Node.js中的集群模块的文档:
http://nodejs.org/api/cluster.html

它声称如下:

当多个进程都accept()相同的底层资源时,操作系统将非常有效地在它们之间进行负载均衡。

这听起来很合理,但是即使经过了几个小时的search,我还没有find任何可以证实的文章或者任何东西,或者说明这个负载平衡逻辑如何在操作系统中工作。

另外,什么操作系统正在做这种有效的负载平衡?

“负载均衡”可能有点糟糕的select,实质上这只是一个问题,操作系统如何select唤醒和/或下一步运行哪个进程。 一般来说,进程调度程序试图根据如下标准来select进程:基于标准给予相同份额的CPU时间给同等优先级的进程,cpu /内存局部性(不要在cpu周围反弹进程)等等。无论如何,通过使用谷歌search你会发现大量的东西来阅读进程调度algorithm和实现。

现在,对于accept()的特殊情况,这也取决于操作系统如何实现唤醒等待accept()的进程。

  • 一个简单的实现就是唤醒每个被accept()调用阻塞的进程,然后让调度器select它们运行的​​顺序。

  • 以上是简单的,但导致了“雷鸣群”的问题,因为只有第一个过程成功接受连接,其他人回去阻止。 更复杂的方法是操作系统只唤醒一个进程; 这里可以通过询问调度器来select唤醒哪个进程,或者,例如,通过在blocking-on-accept()for this-socket列表中select第一个进程。 后者是Linux在十年或更久之后所做的,基于已经由其他人发布的链接 。

  • 请注意,这只适用于阻止accept(); 对于非阻塞accept()(我确信node.js正在做什么),问题变成了select()/ poll()/什么来传递事件到哪个进程阻塞。 poll()/ select()的语义实际上要求所有这些都被唤醒,所以你再次遇到雷鸣的问题。 对于Linux,也可能以类似的方式使用其他具有系统特定高性能轮询接口的系统,可以通过使用单个共享epoll fd和边缘触发事件来避免雷鸣般的畜群。 在这种情况下,事件将只传递给epoll_wait()上阻塞的进程之一。 我认为,类似于阻止accept(),传递事件的过程的select,只是selectepoll_wait()阻塞的进程列表中的第一个特定的epoll fd。

所以至less对于Linux来说,对于阻塞accept()和非阻塞accept()来说,边界触发epoll,在select要唤醒哪个进程时本身没有调度。 但是OTOH,工作负载可能会在进程之间相当平衡,因为系统本质上会按照完成当前工作的顺序循环进程,并返回到epoll_wait()的阻塞状态。