首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Linux epoll 高併發網路模型深度解析:LT/ET 模式、API 詳解、萬級併發聊天室實戰

     編輯:關於C語言

epoll 核心優勢

  • 無需重複註冊:epoll_ctl 一次註冊,epoll_wait 直接返回就緒集合。
  • 只遍歷就緒 fd:O(就緒數) 而非 O(監聽總數),大幅降低 CPU 佔用。
  • 支援邊緣觸發 (ET):配合非阻塞 IO,單次通知可處理全部資料,減少系統呼叫。

兩種觸發模式

模式特性適用場景
LT (Level Triggered)緩衝區有資料就持續通知;支援阻塞/非阻塞簡單可靠、預設模式
ET (Edge Triggered)狀態變化瞬間通知一次;必須非阻塞高效能、需循環讀寫至 EAGAIN

核心 API

int epoll_create(int size);                    // 建立 epoll 實例
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *ev); // 註冊/修改/刪除
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout); // 等待事件
epoll_event 關鍵欄位:
struct epoll_event {
    uint32_t events;   // EPOLLIN, EPOLLOUT, EPOLLET, EPOLLONESHOT...
    epoll_data_t data; // 聯合體:fd / ptr / u32 / u64
};

實戰:萬級併發聊天室服務端 (ET 模式)

#define MAX_EVENTS 10000
int epfd = epoll_create(MAX_EVENTS);
struct epoll_event ev, events[MAX_EVENTS];

ev.events = EPOLLIN | EPOLLET;  // 讀就緒 + 邊緣觸發
ev.data.fd = listener;
epoll_ctl(epfd, EPOLL_CTL_ADD, listener, &ev);

while (1) {
    int n = epoll_wait(epfd, events, MAX_EVENTS, -1);
    for (int i = 0; i < n; i++) {
        if (events[i].data.fd == listener) {
            // 新連線
            int cfd = accept(listener, ...);
            fcntl(cfd, F_SETFL, O_NONBLOCK);  // ET 必須非阻塞
            ev.data.fd = cfd;
            epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &ev);
            send(cfd, welcome_msg, ...);
        } else {
            // 讀取客戶端資料 (循環讀至 EAGAIN)
            handle_client(events[i].data.fd);
        }
    }
}

客戶端處理關鍵 (ET 模式必讀)

void handle_client(int fd) {
    char buf[4096];
    while (1) {
        int r = read(fd, buf, sizeof(buf));
        if (r > 0) broadcast(buf, r);
        else if (r == 0) { close_fd(fd); break; }  // 對端關閉
        else if (errno == EAGAIN || errno == EWOULDBLOCK) break; // 資料讀完
        else { perror("read"); close_fd(fd); break; }
    }
}

壓測結果

10,000 客戶端並發連線,伺服端處理時間 < 1 秒,CPU 佔用極低,驗證 epoll ET 模式高併發能力。

常見坑與最佳實踐

  • ET 模式必須循環讀寫至 EAGAIN,否則資料殘留下次不再通知。
  • EPOLLONESHOT:處理完重新註冊,防止多執行緒並發處理同一 fd 競爭。
  • 邊緣觸發 + 非阻塞 + 循環處理 是高效能鐵三角。
  • 監聽 fd 建議用 LT,避免連線風暴漏通知。

總結

epoll 以「事件就緒通知 + 就緒集合返回」取代 select/poll 的「輪詢全量集合」,配合 ET 模式與非阻塞 IO,成為 Linux 高併發網路伺服器的標準基石。掌握其 API、模式差異、ET 讀寫循環邏輯,是系統級網路程式設計核心能力。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved