libuv_cpp11是一個基於libuv的C++封裝網絡庫。接口較爲簡單易用,並對libuv一些特性做了擴展及優化。壓力測試結果穩定、高效。未發現內存泄漏及崩潰。
- 爲什麼需要封裝libuv
截至目前,C++沒有標準網絡庫,常見的有ACE和boost.asio。ACE較爲龐大臃腫,封裝複雜,個人不推薦。boost.asio是boost庫的一部分,需要依賴boost的部分實現,使用asio需要在項目引入較爲龐大的boost庫。而C語言的網絡庫主要有libevent、libev及libuv。libuv是nodejs的底層,較爲成熟。所以如果在項目需要一套輕量級,且沒有太多依賴的網絡組件,最好的辦法,還是自己封裝一套。
- libuv_cpp11功能簡介
1.實現了C++功能的回調
首先libuv是一個C語言庫,意味着回調函數是C語言的回調,所以直接使用libuv網絡消息回調,相關對象必須是全局的或者static對象,這是令人難以容忍的。這裏通過libuv的用戶數據功能實現了C++風格的回調,回調函數可以類成員函數,或者lambda。同時封裝了TcpServer及TcpClient等類,簡化編程。
2.對線程安全做了優化
libuv是一個非線程安全的庫,跨線程發送數據數不允許的。libuv_cpp11中實現了線程安全的跨線程write數據操作。基於libuv的async異步機制實現,同時在跨線程調用時候會檢查當前調用線程,如果在該loop線程中則直接發送,減少了不必要的性能損耗。實現如下:
void uv::EventLoop::runInThisLoop(const std::function<void()>& func)
{
if (nullptr == func)
return;
if (isRunInLoopThread())
{
func();
return;
}
async_->runInThisLoop(func);
}
同時libuv的aysnc接口存在多次調用一次執行的可能(問題),比如有些操作需要在回調裏面釋放數據,這樣就會內存泄漏。libuv_cpp11中的Async類優化這個問題,確保每次調用一定會被執行。
3.實現了定時器及時間輪
對libuv定時器做了一層封裝,並實現了一個時間複雜度O(1)的時間輪,用於檢測心跳超時。
4.實現整包發送/接受協議機制
實現了ListBuffer和CycleBuffe兩種緩存機制,用於解決TCP的粘包及殘包。數據會重新組成完整的包數據用於讀取。性能測試顯示CycleBuffe會損失20%~30%的性能。
5日誌接口
libuv_cpp11沒有實現日誌功能,但是保留了接口,可以註冊/綁定到自定義日誌庫中使用。
- libuv_cpp11的使用
詳見example文件夾:https://github.com/wlgq2/libu...