Qt界面開發紀實:Qt 計時器 多線程加鎖 C++差錯控制 try throw 與catch(QT C++ MSVC MinGW )(2)

Qt界面開發紀實:Qt 計時器 多線程加鎖 C++差錯控制 try throw 與catch(QT C++ MSVC MinGW )(2)

上一篇博客 https://blog.csdn.net/TiffanyXYf/article/details/100011341 中主要介紹了開發工具的配置,信號與槽,以及簡略地說明了多線程實現界面刷新。本篇博客繼續記錄採坑事件。

Qt 計時器Qtimer

根據甲方爸爸對於顯示界面刷新的要求,其中有一項功能是:實現每0.2s刷新一次界面 實現這個功能最簡單的方式就是使用一個計時器,讓這個計時器不斷地每0.2s觸發一次槽函數(顯示圖片),從而實現界面0.2s刷新一次界面。Qtimer的使用包括三部分:1.定義一個計時器,2.將計時器的timeout()函數與一個對應的槽函數配對(我這裏需要將timeout函數與某一個子線程的槽函數相連,因爲需要顯示的圖片來自子線程,這個sing_imgprocess()函數還會發出其他信號函數,從而觸發主線程刷新界面),3.啓動計時器(如圖直接start即可)。
頭文件:#include<QTimer>
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
計時器這裏遇到的一個坑:多線程如果訪問了同一個變量的話,系統會出現內存訪問衝突。我剛接觸多線程,沒有幫線程加鎖。在實現0.2s刷新之前,一個子線程+一個主線程是可以連續穩定運行的。但是寫了0.2s刷新之後,我的代碼開始變得不穩定,以隨機時間長度崩潰,短則30分鐘,長則4個小時以上。 後來師弟發現在Qt項目中,即使兩個線程一起讀一個變量也需要加鎖,加了鎖之後,上述問題依舊沒有解決。大概過了一週,發現是上圖:timeout對應的那個槽函數漏掉加鎖了
那個函數原來的定義是:判斷是否0.2s刷新以及要顯示的這個圖片是否爲空,然後直接發信號給主線程顯示。其中showImg是線程類中的一個成員,所以可以在線程對象中可以修改和使用
在這裏插入圖片描述
加鎖之後,這個函數變成:核心思想就是訪問某個可能被多個函數使用的變量時,將其鎖住,拷貝成另一個變量,再使用另外一個變量進行操作,從而避免訪問衝突,下圖就是一個例子。
在這裏插入圖片描述

線程鎖

上一部分提到了給變量加鎖,這一部分具體說說怎麼使用這個鎖(我這裏使用的時最基礎的鎖,Qt中還存在別的更高端的鎖,如果感興趣可以去網上查看)

首先:鎖是一個全局變量,我有多個cpp文件需要用到鎖,所以聲明鎖的時候要用extern這裏涉及到一個知識點:如何再多個cpp文件中使用同一個變量

例如,在A.h文件中聲明瞭一個鎖
在這裏插入圖片描述
在A.cpp中再次聲明一下
在這裏插入圖片描述
如果在A.cpp中沒有聲明的話編譯時會報錯:
在這裏插入圖片描述
在B.cpp中需要用到這個鎖:
則可以直接在B.cpp中include A.h,這樣就可以直接使用,而不需要在B.cpp中重新聲明。

使用鎖也很簡單
多個線程需要用同一個鎖,只需要在線程類中聲明一個鎖,然後建立線程的時候將所有的鎖都指向這個全局的鎖

如圖:
B.h中定義一個鎖:
在這裏插入圖片描述
B.cpp 中指向全局鎖mutex1
在這裏插入圖片描述
B.cpp 中,其他函數需要使用鎖時:直接對需要的變量進行lock 和unlock就行了。
在這裏插入圖片描述
需要說明的是:我使用的這個鎖比較基礎,lock和unlock必須是配對使用的,如果存在鎖住的代碼中有return或者throw的操作,導致只執行了lock而沒有執行unlock會導致死鎖。 Qt中有其他的鎖,可以在上述特殊情況下,自動執行一個函數,使其unlock,由於沒有使用,我這裏就不多說了。
總之,通過對線程加鎖,我的代碼隨機閃退的情況得到了解決。而且不知道爲什麼這裏兩個線程同時讀也需要加鎖,而一般“讀讀”是不需要加鎖的

差錯控制 throw與try 和catch

相機操作和圖像處理過程中會存在很多異常情況,比如相機採集圖片時遇到殘幀,圖片處理的圖片質量達不到要求。差錯控制的目的是保證程序在遇到這些異常情況的時候依然能運行下去

throw可以扔出任何類型的錯誤,甚至結構體,類都可以被拋出,但是一般不需要那麼麻煩。
我使用的有兩種:相機相關的錯誤和圖片處理相關的錯誤
string camera_err=“camera_err”;
throw(camera_err)

int image_err=111;
throw(image_err);

try
{…執行的程序}
catch(camera_err){…你的處理}
catch(image_err){…你的處理}

這樣只要差錯能夠被catch到,程序運行就不會受到影響
有可能的坑:如果你throw了一個錯誤,但是沒有catch,則程序會在throw那裏直接退出,或者報嚴重的錯誤,所以自己定義的差錯,一定要記得都catch。

下一篇:會接着介紹學會的操作與遇到的坑

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