關於驚群問題

2022-07-06 19:12:07 字數 884 閱讀 7150

簡單說來,多執行緒/多程序(linux下執行緒程序也沒多大區別)等待同乙個socket事件,當這個事件發生時,這些執行緒/程序被同時喚醒,就是驚群。可以想見,效率很低下,許多程序被核心重新排程喚醒,同時去響應這乙個事件,當然只有乙個程序能處理事件成功,其他的程序在處理該事件失敗後重新休眠(也有其他選擇)。這種效能浪費現象就是驚群。

驚群通常發生在server 上,當父程序繫結乙個埠監聽socket,然後fork出多個子程序,子程序們開始迴圈處理(比如accept)這個socket。每當使用者發起乙個tcp連線時,多個子程序同時被喚醒,然後其中乙個子程序accept新連線成功,餘者皆失敗,重新休眠。

那麼,我們不能只用乙個程序去accept新連線麼?然後通過訊息佇列等同步方式使其他子程序處理這些新建的連線,這樣驚群不就避免了?沒錯,驚群是避免了,但是效率低下,因為這個程序只能用來accept連線。對多核機器來說,僅有乙個程序去accept,這也是程式設計師在自己創造accept瓶頸。所以,我仍然堅持需要多程序處理accept事件。

其實,在linux2.6核心上,accept系統呼叫已經不存在驚群了(至少我在2.6.18核心版本上已經不存在)。大家可以寫個簡單的程式試下,在父程序中bind,listen,然後fork出子程序,所有的子程序都accept這個監聽控制代碼。這樣,當新連線過來時,大家會發現,僅有乙個子程序返回新建的連線,其他子程序繼續休眠在accept呼叫上,沒有被喚醒。

但是很不幸,通常我們的程式沒那麼簡單,不會願意阻塞在accept呼叫上,我們還有許多其他網路讀寫事件要處理,linux下我們愛用epoll解決非阻塞socket。所以,即使accept呼叫沒有驚群了,我們也還得處理驚群這事,因為epoll有這問題。上面說的測試程式,如果我們在子程序內不是阻塞呼叫accept,而是用epoll_wait,就會發現,新連線過來時,多個子程序都會在epoll_wait後被喚醒!

關於 多程序epoll 與 「驚群」問題

遇到問題 手頭原來有乙個單程序的linux epoll伺服器程式,近來希望將它改寫成多程序版本,主要原因有 在服務高峰期間 併發的 網路請求非常海量,目前的單程序版本的程式有點吃不消 單程序時只有乙個迴圈先後處理epoll wait 到的事件,使得某些不幸排隊靠後的socket fd的網路事件處理不...

linux驚群問題 select, epoll

今天測試udp伺服器程序時發現log中記錄了當程序收到乙個請求後,會有多條失敗處理記錄,同時有一條成功處理記錄。伺服器程序使用sellect模式,通過fork四個子程序來監聽同乙個socket。發現問題後初步懷疑是出現了驚群現象。但是,聽說現代核心已經解決了驚群問題,程式也可以確定也沒有問題,就奇怪...

nginx的驚群問題

問題 nginx是乙個高效能網路併發伺服器,它的程序模型是,多程序模型,有乙個master程序,會啟動多個worker程序,一般是根據cpu核心個數決定 然後每個程序又利用io多路復用技術,監聽多個socket,達到高併發的能力。它存在乙個問題就在於,每個worker子程序都會去accept 監聽套...