簡體   English   中英

C 語言中帶有 epoll 和 EPOLLET 的多線程 TCP 偵聽器

[英]Multithreaded TCP listener with epoll and EPOLLET in C

我想使用 epoll 和EPOLLET編寫一個多線程 TCP 偵聽器。

我已經看到有幾種可能性:

  1. 每個線程都有自己的 epoll fd,使用SO_REUSEPORT (但僅限 Linux 內核 3.9)執行bind() ) 並處理自己的連接。 在這種情況下不需要EPOLLONESHOT ,因為每個線程都處理自己的文件描述符。

  2. 有一個接受連接的主線程和處理這些連接的幾個工作線程。 每個工作線程都有自己的 epoll fd。 在這種情況下,主線程如何在工作線程之間公平分配連接? 它可以使用循環方式將文件描述符添加到另一個線程的 epoll fd 中(但可能發生該特定線程仍在忙於處理另一個連接)。 或者可以將連接添加到全局隊列,主線程將使用pthread_cond_signal() ,但是我們需要一個互斥鎖和一個條件變量。

  3. 有一個接受連接的主線程和處理這些連接的幾個工作線程。 有一個全局 epoll fd,在這種情況下將需要EPOLLONESHOT ,因此並非所有線程都被同一個事件喚醒。

我知道,如果使用EPOLLET ,一旦我收到有關事件的通知,我必須耗盡 fd,直到我得到EAGAIN

如果不支持套接字選項SO_REUSEPORT (舊內核),哪個選項最好?

  1. 1. 但沒有 SO_REUSEPORT 的變體是有一個共享的監聽套接字。 每個工作線程運行自己的事件循環,除了處理自己的連接之外,它們還在偵聽套接字上執行非阻塞的 accept()。 有關更詳盡的描述,請參見例如http://aosabook.org/en/nginx.html
  1. 不使用SO_REUSEPORT的解決方案是擁有一個通用的 epoll fd 和一個在所有線程之間共享的通用偵聽器。 EPOLLONESHOT是必需的,因此一次只有一個線程處理某個 fd 的事件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM