「負荷分散」という言葉の選択はおそらく少し不適切です。本質的には、OS がどのプロセスを起動および/または次に実行するかをどのように選択するかという問題です。一般に、プロセス スケジューラは、CPU 時間を同じ優先度のプロセスに均等に配分する、CPU/メモリの局所性 (CPU の周りにプロセスをバウンスしない) などの基準に基づいて、実行するプロセスを選択しようとします。プロセス スケジューリングのアルゴリズムと実装については、読むべきものがたくさんあります。
ここで、accept() の特定のケースについては、OS が accept() を待機しているウェイクアップ プロセスをどのように実装するかにも依存します。
簡単な実装は、accept() 呼び出しでブロックされたすべてのプロセスを起動し、スケジューラに実行順序を選択させることです。
上記は単純ですが、最初のプロセスのみが接続の受け入れに成功し、他のプロセスはブロックに戻るため、「雷鳴の群れ」の問題につながります。より洗練されたアプローチは、OS が 1 つのプロセスのみを起動することです。ここで、起動するプロセスの選択は、スケジューラに問い合わせるか、たとえば、ブロックされた on-accept()-for-this-socket リストの最初のプロセスを選択するだけで行うことができます。後者は、他の人がすでに投稿したリンクに基づいて、Linuxが10年以上前から行っていることです。
これは、accept() をブロックする場合にのみ機能することに注意してください。ノンブロッキングのaccept()(これはnode.jsが行っていることだと確信しています)の場合、select()/poll()/ whateverでイベントを配信するためにどのプロセスがブロックされるかが問題になります。poll()/select() のセマンティクスは、実際にはそれらすべてをウェイクアップすることを要求するため、雷鳴の群れの問題が再び発生します。Linux の場合、おそらく同様の方法で、システム固有の高性能ポーリング インターフェースを備えた他のシステムでも、単一の共有 epoll fd とエッジ トリガー イベントを使用することで、雷鳴の群れを回避することができます。その場合、イベントは epoll_wait() でブロックされたプロセスの 1 つだけに配信されます。accept() をブロックするのと同様に、イベントを配信するプロセスの選択は、
そのため、少なくとも Linux では、エッジ トリガー epoll を使用したブロッキングの accept() と非ブロッキングの accept() の両方で、ウェイクするプロセスを選択する際のスケジューリング自体はありません。しかし、OTOH、基本的にシステムは現在の作業を終了して epoll_wait() のブロックに戻る順序でプロセスをラウンドロビンするため、ワークロードはおそらくプロセス間でかなり均等にバランスが取れています。