用 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