PF2.1版本總結,在設計過程當中遇到的問題以及技術分享

  在距離上一次的版本發佈已通過去4個月的時間,由於我的的能力以及時間有限,因此此次的版本會推遲這麼久。但是不管怎樣,PF2.1帶着自身的完善總算不負所望推出。在此次的版本調整中讓我深有體會到了程序設計中的幾大問題:安全、性能、穩定。如何設計出一個高效穩定的框架時,天然須要對所運用的語言的熟知,在這期間我一直參考了《effective c++》這本對C++語言總結的十分詳細的資料,結合了最新C++11的新特性。
版本更新
  一、增長:cache模塊
  二、增長:lua插件中的dcache模塊
  三、增長:對應的windows專用版本倉庫
  四、優化:利用C++11新特性修改basic的type::variable_t的實現機制
  五、優化:動態分配內存類修改、替換數據庫查詢中的結果緩存數據爲堆的實現方式(以前棧的方式會致使windows棧溢出)
  六、修復:share::Map、share::lock/unlock、db::Query在多線程不能正常工做的問題
 
  在此次的版本中遇到的最多問題是多線程下以及windows平臺上兼容的問題,深入體會到VC的實現與GNU的區別。雖然平臺之間存在兼容性,但是一些硬性的C++標準是不會有什麼區別的。對於存在的問題,該版本進行了大刀闊斧的修正,絕對沒有存在任何僥倖和姑息。我將從如下幾個方面來分享:共享鎖、泛型編程、線程池。
 
共享鎖
  共享鎖的實現目的是爲了在同時訪問這些公用的內存時數據的正確性,這與多線程中的鎖是相似的。不過共享鎖的實現是以std::atomic的CAS(compare_exchange_weak)方式實現的,這方面能夠查詢一下相關的資料,固然這是在C++11標準中的,舊的標準沒有。
  在pf_cache::DbStore以及核心的share::Map中我都用到了共享鎖,當前這個共享鎖的實現可能並不完美,不過在測試下能夠進行正常的工做。
  std::atomic的數據是在共享內存中存在的,所以在咱們隊單個對象節點(node)進行操做時須要保證它是被正確修改的,即鎖的自己須要保證安全和可靠。同時最重要一點的是咱們再進行一個總體操做時,好比share::Map中刪除一個數據須要涉及到內部內存的變更,那麼這整個改變應該是惟一的,所以在這過程當中咱們須要全程加鎖,避免另外一個刪除操做(多線程)修改咱們這些數據,致使操做內存的混亂錯誤。
 
泛型編程
  什麼是泛型編程?
  咱們要理解它的含義,那麼咱們能夠看一個類型,那就是void *,它表示什麼意思呢?咱們能夠稱它爲空指針,同時它還有另外一個名字:泛型指針。
  爲何void *被叫作泛型指針呢?想一想咱們用它的場景,應該不難發現,它的最大做用時表示任何的指針,它能夠很輕鬆的轉換爲你想要的類型,所以它自己是與類型沒有任何關係的。
  泛型編程和void *指針同樣,它自己是和類型無關的,原則上是通用的。而在C++中的實現方式,是以類(結構體)和函數模板(template)的方式。
  本次版本中就使用了模板的方式重構了type::variable_struct,從原來約1500行代碼縮短到約600行,這可見泛型編程的優越。
  不過在模板中我以爲須要注意的是模板特化的實現方式,這一點能夠查找相關資料便可。
 
線程池
  提到池的概念,有許多人可能會想到內存池,這是由於咱們在學習過程當中許多書籍上都會有相關的介紹。線程池的概念卻有些區別,雖然它也是一個至關於存儲許多線程的容器,不過我認爲它更像一個工做小組。
  咱們之因此要用到多線程和線程池的緣由,就是爲了充分利用機器的線程優點,就比如原來只有一我的作的工做,如今分攤到許多人的身上,天然這樣的工做效率是成倍的提高的。而PF如今的線程池在類pf_sys::ThreadPool中,是一位開源貢獻者實現的。它利用了C++的新特性,在線程池構造時便建立了許多的工做線程,並讓它們進入休眠中,當有一個新的任務時,它會利用線程條件通知的方式喚醒線程進行工做。
  在pf_cache::DbStore中的waitquery便使用了線程池,有興趣的能夠去查看,天然也歡迎你們能指正錯誤。
 
附錄
  github for linux:   https://github.com/viticm/plainframework
  github for windows:  https://github.com/viticm/pf_win
  討論QQ羣:  348477824
相關文章
相關標籤/搜索