用 Go 基於 epoll 實現一個最小化 IO 庫

圖片拍攝於 2023 年 04 月 27 日 日本鎌倉

各位大佬,還不會 io_uring,輕噴。

不鴿了不🐦了。

目前 Go 圈有很多款異步的網絡框架: evio,nbio,gnet,cloudwego/netpoll......,

排名不分先後。

這裏面最早的實現是 evio。evio 也存在一些問題,之前也寫過 evio 文章介紹過。其他比如 nbio 和 gnet 也寫過一些源碼分析。

這些框架在應用層上做了很多優化,比如: Worker Pool,Buffer,Ring Buffer,NoCopy......。

都分析了好幾篇代碼了,咋麼說也得自己動手搞一個來達成學習目的。

沒錯,這就是 easyio 的由來。easyio 是一個最小化的 IO 框架,只實現最核心的部分,加起來不超過 500 行代碼。

也沒有用戶端上層應用的優化,且目前只實現了 linux 的 epoll,以及只能運行 tcp 協議。

大概結構如下,具體可以看代碼~~,

簡單的 demo,

服務端:

上面的代碼,初始化一個 easyio,啓動一個 tcp 服務,監聽端口 8090,options 裏面設置 epoll 的數量,以及設置事件處理器。

當一個新連接到來時會回調 OnOpen 函數,此時你可以設置自定義的 ctx,那麼當對應連接讀事件到來 OnRead 回調,你可以拿到之前設置的 ctx,調用 conn.Read 讀取數據,且通過 Write 向對端寫數據。

這裏需要注意的是,一個連接如果數據沒讀完,當 OnRead 執行結束,下一輪會繼續觸發回調代碼,因爲底層 epoll 採用的是 LT 觸發方式。

簡單的客戶端

看懂和會寫出來是完全不一樣的概念。理論與實踐是相輔相成的,只有理解了理論並將其應用於實踐中,我們才能真正掌握知識。

因爲之前讀者問過一些問題,我計劃編寫一個從零開始實現的 easyio 系列教程,希望能夠幫助一些小白通過實踐來加深對這個主題的理解。

如果你對這個系列感興趣,請在下方留言或點贊。

決定要做的話,整個系列大概可以拆分成 5~6 篇文章 (當然不收費~)。

最後讓這個世界充滿愛~~~

easyio 源碼: https://github.com/wuqinqiang/easyio

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/YncTa7XMSu4UxhpUFv4q4Q