Qt 多執行緒與資料庫操作需要注意的幾點問題

2021-06-19 10:11:35 字數 1757 閱讀 7288

徹底拋棄mfc, 全面應用qt 已經不少時間了。除了自己看書按步就班做了十幾個驗證性的應用,還正式做了3個比較大的行業應用,總體感覺很好。native c++ 下, qt 基本是我用過的最簡便的介面庫了。遇到了一些問題,大都解決的很順利,回頭想想,還是有幾個問題很有意思,尤其是資料庫應用。這裡把我的經歷分享一下。

1、執行緒內註冊與連線資料庫的競爭問題

文件上對多執行緒下資料庫應用的注意事項寫的很簡明,乙個執行緒建立的 qsqldatabase 物件和 查出來的 qsqlquery 物件只能給本執行緒用(注意,是物件,不是資料庫連線本身,連線本身用名字可以多執行緒使用),其他情況是「不支援的」。在乙個需要有幾個執行緒併發訪問不同資料庫的應用中,我首先試圖在各個執行緒的起始分別以不同的名稱呼叫  adddatabase / database 、open,但是程式偶然會崩潰,跟蹤後發現,雖然qt 聲稱很多方法是「執行緒安全」的,但是幾個方法串起來,就出問題了。qt 會動態的載入資料庫的plugin, 載入 plug in 的部分,涉及到對本地庫檔案的管理,這一部分,出現了競爭。於是,很自然的想到在初始連線部分設定 mutex 保護,從 adddatabase / database到 open 的部分,要保證其原子性,問題再也沒有出現。

2、資料庫連線意外斷裂後,恢復連線的問題

在mfc 中,一旦中途tcp連線斷裂,直接重新 open 就可以了。在qt 裡,這一招不好使了。即便 呼叫了 close ,再次open 也是不行的。處理方法:

在檢測到問題出現後,關閉連線,並 removedatabase;   而後,不要立刻 adddatabase, 反而是要回到該連線所在的事件迴圈。沒有詳細跟原始碼,很可能在 removedatabase 後的事件迴圈中,qt 內部做了一些釋放操作。   怎麼辦呢, 可以設定乙個恢復定時器,比如 1分鐘,重新 adddatabase,就可以啦。如果心急的話,直接顯式呼叫processevent() 方法強制迴圈。

在多執行緒下,注意1中的問題,需要 mutex保護。

3、資料庫外掛程式的依賴性問題

在 windows 下,有時我們的機器上按了好幾個 qt 版本,path裡索性神馬也不設定,依賴開發環境的繼承環境適應不同的版本。這有兩個問題。一是發布程式的時候,資料庫驅動依賴的dll 也要與可執行檔案在同一路徑下發布。比如 mysql 的 dll, postgresql 的依賴等。二是在整合開發環境中,這些依賴也要位於執行檔資料夾下。否則,會造成雖然可以列舉到可用驅動,但是死活連線不上。除錯一下就知道,原來是在路徑中找不到依賴項,導致dll載入失敗哦!

qt的資料庫操作自成一派,相對於複雜的 ado \odbc\dao\oledb 等傳統 c++ 訪問資料庫的方法,還是很先進的,充分體現了 oo 的理念。對資料庫的封裝,想法是很有意思的。設計者把程序內的資料庫連線作為一種資源,每個連線有乙個唯一的名字,可以通過全域性的 adddatabase, removedatabase, clonedatabase 來增刪,想用的時候,直接用全域性的 database 來獲取。這樣的好處,是大大節省了開發者的負擔。以前為了傳遞乙個資料庫連線的變數,必須在很多方法入庫處新增指向這個變數的指標或者引用,有時候不得不在物件的屬性中加入靜態的變數,來記錄這個連線。現在,什麼時候想用,給個名字就可以了,不需要傳遞。當然,文件說的是比較簡化的,至少有兩點要注意,

1)這些增刪方法號稱是執行緒安全的,但是,在實際應用中,還是要注意用 mutex 保護全域性建立流程,或者,過載這些函式,建立自己的安全版本。

2)乙個執行緒建立的資料庫物件(如 adddatabase 的返回值)只能在同一執行緒使用,但是,adddatabase 註冊的連線(名字是開發者定)可以跨執行緒使用,唯一需要注意的是,在呼叫全域性方法的時候,要有原子保護。

多執行緒程式設計需要注意的問題

1 執行緒的優先順序 多執行緒程式設計中要注意協調好各個執行緒的優先順序。一般來說,控制線程的優先順序要高於 worker執行緒。這樣做,可以保證client 終端使用者或者其他模組 盡快得到響應。當控 制執行緒是與終端使用者互動的介面執行緒時更應如此,如果介面執行緒優先順序較低,介面可能 較長時間...

SharePoint的資料庫效能需要注意的一點

建立sharepoint的時候,可能會忽略在資料庫層次的兩個設定 initial size 和 autogrowth 這兩個選項的預設值都需要修改一下的.initial size,如果說我們的content db大小已經是4 tb了.那麼我們設定crawlstoredb的初始大小為500 mb就是不...

Qt中關於執行緒需要注意的地方

以前一直沒弄多執行緒的東西,這幾天試了以下,結果弄出很多問題出來,記錄下。如何刪除執行緒 為了可以動態調節執行緒的數量,我把所有的執行緒都放在乙個vector中,當需要的數量大於vector.count 的時候則建立並加入執行緒 當需要減少執行緒數的時候則通過如下 實現 qthread thd ve...