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

從 libuv 到 epoll:Linux 網絡開發庫學習路徑與核心原理實戰

     編輯:關於C語言

從 libuv 到 epoll:Linux 網絡開發庫學習路徑與核心原理實戰

前言:為什麼要學 libuv 與 epoll

libuv 是 Node.js 的底層跨平台異步 I/O 庫,封裝了 Windows IOCP、Linux epoll、macOS kqueue 等。掌握它能深入理解現代高併發網絡模型。但 libuv 封裝層較厚,源碼閱讀門檻高。建議學習路徑:

  1. 官網下載源碼,閱讀 README.md 編譯安裝(遇問題上 Stack Overflow)。
  2. 研讀中文版《libuv 書籍》https://www.nowx.org/uvbook/,配套 demo 代碼 逐行敲寫。
  3. 對照源碼理解事件循環、Handle/Request、線程池、定時器實現。
  4. 最終回歸基礎:手寫 epoll 服務器,理解就緒通知、邊緣觸發(ET)、水平觸發(LT)本質。

epoll 核心四大函數

int epoll_create(int size);          // 創建 epoll 實例,返回 fd
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); // 註冊/修改/刪除 fd
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout); // 等待就緒事件
// 事件結構
struct epoll_event {
    uint32_t events;  // EPOLLIN, EPOLLOUT, EPOLLET, EPOLLONESHOT...
    epoll_data_t data; // 聯合體:fd / ptr / u32 / u64
};

實戰 1:標準輸入監控(Hello epoll)

#include <stdio.h>
#include <sys/epoll.h>
#include <unistd.h>
#define MAX_BUF 255
int main() {
    int epfd = epoll_create(1);
    struct epoll_event ev = { .events = EPOLLIN, .data.fd = STDIN_FILENO };
    epoll_ctl(epfd, EPOLL_CTL_ADD, STDIN_FILENO, &ev);
    for (;;) {
        struct epoll_event evs[1];
        int nfds = epoll_wait(epfd, evs, 1, -1);
        if (nfds > 0 && evs[0].data.fd == STDIN_FILENO) {
            char buf[MAX_BUF];
            int len = read(STDIN_FILENO, buf, MAX_BUF-1);
            buf[len] = '\0';
            printf("Input: %s", buf);
        }
        if (random() % 100 >= 90) break; // 隨機退出演示
    }
    close(epfd);
    return 0;
}

實戰 2:epoll + pthread 簡易 HTTP 服務器(ET 模式)

關鍵點:

  • EPOLLET 邊緣觸發:必須配合非阻塞 fd,一次性讀寫完緩衝區。
  • 主線程 epoll_wait 分發新連接,pthread_create 處理業務(讀取請求、寫回響應)。
  • 管道/信號量可用於線程間同步,此處為教學簡化直接在工作線程 read/write。
// 編譯:gcc -g -Wall -o epoll_srv epoll_srv.c -lpthread
// 完整代碼見原文,核心流程:
// 1. socket/bind/listen + 設置非阻塞 + SO_REUSEADDR
// 2. epoll_create + EPOLL_CTL_ADD 監聽 fd (EPOLLIN|EPOLLET)
// 3. 循環 epoll_wait:
//    - 新連接:accept → 設置非阻塞 → EPOLL_CTL_ADD 客戶端 fd
//    - 可讀事件:pthread_create 處理請求/響應
// 4. 工作線程:read 循環 → write 響應 → close fd → pthread_exit

libuv 學習心得與避坑

  • ✅ 優點:跨平台、API 相對乾淨、Node.js 生態驗證過生產環境。
  • ⚠️ 缺點:全域變量多、隱式 header 包含多、線程池與事件循環耦合、調試困難。
  • 💡 建議:學會 libuv 後,嘗試手寫一個精簡的 Reactor/Proactor 框架,理解「為什麼要這樣設計」。

vim 開發配置推薦(~/.vimrc)

set fenc=utf-8 | set fencs=utf-8,gbk,gb2312
set nocompatible | set number | set autoindent | set smartindent
set tabstop=4 | set shiftwidth=4 | set ruler | set incsearch
set ignorecase | set showmatch | syntax on

總結

網絡開發沒有銀彈。libuv 適合快速落地產品;epoll 適合深入內核機制、打造自研高性能框架。建議:先用 libuv 交付,再啃 epoll 源碼內功。

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