對libuv的C++封裝

libuv_cpp11是一個基於libuv的C++封裝網絡庫。接口較爲簡單易用,並對libuv一些特性做了擴展及優化。壓力測試結果穩定、高效。未發現內存泄漏及崩潰。

  • 爲什麼需要封裝libuv

截至目前,C++沒有標準網絡庫,常見的有ACE和boost.asio。ACE較爲龐大臃腫,封裝複雜,個人不推薦。boost.asio是boost庫的一部分,需要依賴boost的部分實現,使用asio需要在項目引入較爲龐大的boost庫。而C語言的網絡庫主要有libevent、libev及libuv。libuv是nodejs的底層,較爲成熟。所以如果在項目需要一套輕量級,且沒有太多依賴的網絡組件,最好的辦法,還是自己封裝一套。

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沒有實現日誌功能,但是保留了接口,可以註冊/綁定到自定義日誌庫中使用。

詳見example文件夾:https://github.com/wlgq2/libu...

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章