qt中的線程重入問題

 昨天晚上寫程序的時候遇到了一個問題,我想在子線程中操作父線程的類成員,但是每次都是在link的時候出現access violation,把子線程類聲明成父線程的友元類也沒用。

 

很費解,因爲按照操作系統原理上的解釋,一個進程中的所有線程的數據是可以共享的,並且C++的類有可重入機制,那麼爲什麼子線程仍然無法訪問父線程的資源?查閱了一些資料,總結了一些東西,發現自己對重入的理解還是比較淺顯,很多地方需要加深理解。

 

首先就是重入的概念,重入,也就是reentrancy,從字面上很好理解,也就是“重複進入”,如果一個函數可以被多個程序同時調用,那麼這個函數就是可重入函數,可重入帶來的一個問題就是線程安全問題,如果可重入函數所操縱的數據全部都是棧中的臨時數據,那麼就不會存在安全問題,但如果兩個線程同時操作一個變量,那就會產生併發問題,這時候需要引入互斥變量來避免此類問題。因此,我們提倡線程中所使用的函數,應該是既可重入,又安全的。

 

具體到QT中,他的大多數類中的方法都是可重入的,但是是非線程安全的,但是一些常見的multi-thread類則是線程安全的,包括:QMutex,QCoreApplication::postEvent()等。值得注意的是,qt中大部分GUI類是不可重入的,在MFC中也是一樣。原因是界面類往往處於消息循環狀態,如果其他線程改變了界面類的佈局,往往會導致crash。

 

最後一點要說明的是,在Qt Assistant的reentrancy and thread-safety這章裏,最後提到了這樣一段話:Terminology in the multithreading domain isn't entirely standardized. POSIX uses definitions of reentrant and thread-safe that are somewhat different for its C APIs. When using other object-oriented C++ class libraries with Qt, be sure the definitions are understood. 也就是說,qt中使用的多線程方法並沒有完全的標準化,因此使用QT的多線程方法和其他庫做交互的時候,一定要注意定義方式。

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