2010-01-18 23 views
7

任何人都可以請幫我回答關於epoll_wait的問題。epoll性能

  1. 是不是矯枉過正使用調用epoll_wait上設置爲服務於約100K的活動套接字相同FDS多線程?或者僅僅創建一個線程來執行epoll_wait就足夠了?

  2. 例如,只有一個套接字準備好讀取數據時,會從epoll_wait中喚醒多少個線程?我的意思是,當有兩個或更多的線程從epoll_wait喚醒但是在結果事件中會有相同的fds時,是否會出現這種情況?

  3. 組織服務器中與多個活動客戶端(例如50K +)一起工作的線程的最佳方式是什麼?我認爲最好的方法是:1 I/O工作線程它執行epoll_wait和I/O操作。 + 許多數據處理線程它將處理從I/O工作線程接收到的數據(可能需要很長時間,比如任何遊戲邏輯),併爲I/O工作線程編寫新數據以發送給客戶端。我是否正確地使用這種方法,或者任何人都可以幫助我找出組織這個方法的最佳方法?

在此先感謝,瓦倫丁

回答

7
  1. 使用epoll的,你想要的大小你的線程總數達到物理CPU內核的數量(或超線程調度單元),你想用它來處理。僅使用一個線程進行工作意味着一次最多隻有一個核心處於活動狀態。

  2. 它取決於epoll文件描述符的模式。事件可以是「邊緣觸發」,這意味着它們只能以原子方式發生,或者「電平觸發」,這意味着如果緩衝區中有空間,任何調用者都會獲取事件。

  3. 沒有足夠的信息來說。爲了簡單起見,我建議不要使用特殊用途的線程,並簡單地在收到它的線程中處理每個事件的「命令」。但顯然這取決於你的應用程序的性質。

+0

因此,如果我理解正確,最好的模式看起來是下一個方法: 創建與系統中的核心數相等的I/O線程數,並使用ET epoll_wait。每個線程都有自己的fd子集。例如IC2Q處理器的4個線程。每個線程處理25K連接,總共100K。 而下一個問題: 我是否需要單獨的線程,將epoll_wait監聽器套接字和管理在哪些子集的新接受的套接字將被添加?並且在一個線程中使用epoll_ctl添加新接受的fd是否是線程安全的,而其他線程是否正在對此子集進行epoll_wait? – Valentin 2010-01-19 09:19:18

+0

實際上,我會等待所有線程中的所有描述符。除非您知道可以通過隔離特定CPU上的相關工作來贏得緩存效果,否則通常會造成這種分區的損失。你最終會餓死一個CPU而另一個仍然有可以完成的工作。是的:epoll操作是原子的(儘管顯然你需要自己鎖定任何自己的bookeeping)。 – 2010-01-19 18:50:51

+0

ET epoll_wait將如何表現?所有線程是否會從epoll_wait喚醒?或者只有一個線程?如果我理解正確,ET epoll_wait是原子的,並且對於現成的fd只會發生一次。例如:我有2個fds和2個等待epoll_wait的線程。 1 fd準備就緒,只有1個線程會恢復,如果其他fd在第一個線程處理完第一個fd,第二個線程將恢復。安迪,這是正確的嗎? – Valentin 2010-01-21 09:27:46

-1

其實這是一個錯誤的epoll用例。

你絕對不能在線程之間共享epoll fd。否則,你有可能一個線程在同一個fd上讀取一個fd和另一個線程上的傳入數據的一部分,而無法知道哪部分數據在另一個之前。

只需在調用epoll_wait的每個線程中調用epoll_create即可。否則,I/O壞了。

+0

對我來說,就像你把epoll fd與實際套接字的fd混淆一樣。實際上,在多個線程中使用epoll是絕對有可能的,這是使用它的一個要點。爲了在線程之間不存在爭用條件,您需要使用'EPOLLONESHOT'或者在更新的內核中使用'EPOLLEXCLUSIVE'。 [這個偉大的博客](https://idea.popcount.org/2017-02-20-epoll-is-fundamentally-broken-12/)解釋了細節。 – kralyk 2017-09-30 17:59:14