詳細介紹:
在複雜函數和聲明中,在異常處理中,鎖定和解鎖一個QMutext對象不但很容易犯錯,還很難調試。
下面的QMutexLocker使用場景,會告訴你如何恰當地定義mutex。
函數中,哪裏需要被鎖定,就在哪裏創建QMutexLocker。一旦QMutexLocker對象被創建,互斥體就被鎖定了。
unlock()和relock()可用來解鎖互斥體。即使互斥體已被鎖定,當QMutexLocker對象被析構摧毀後,互斥體會自動解鎖。
例子:在函數開始處,鎖定互斥體對象,在每個函數出口處解鎖互斥體。
int complexFunction(int flag)
{
mutex.lock();
int retVal = 0;
switch (flag) {
case 0:
case 1:
retVal = moreComplexFunction(flag);
break;
case 2:
{
int status = anotherFunction();
if (status < 0) {
mutex.unlock();
return -2;
}
retVal = status + flag;
}
break;
default:
if (flag > 10) {
mutex.unlock();
return -1;
}
break;
}
mutex.unlock();
return retVal;
}
開發這樣的函數會更麻煩,也更容易出錯。使用QMutexLocker不僅極大地簡化了編碼,代碼易讀性也更高了:
int complexFunction(int flag)
{
QMutexLocker locker(&mutex);
int retVal = 0;
switch (flag) {
case 0:
case 1:
return moreComplexFunction(flag);
case 2:
{
int status = anotherFunction();
if (status < 0)
return -2;
retVal = status + flag;
}
break;
default:
if (flag > 10)
return -1;
break;
}
return retVal;
}
QMutexLocker對象是一個自動變量,函數返回時,對象自動被摧毀析構,互斥體隨之自動解鎖。
同樣的道理也適用於會拋出異常的編碼。
若函數已鎖定互斥體,但沒有捕獲到函數內發生的異常。
那麼只有當異常被傳遞到調用它的函數的棧時,互斥體才能被解鎖.
QMutexLocker也提供了QMutexLocker運行過程中可返回互斥體的成員函數。
像QWaitCondition::wait(),這樣需要訪問互斥體的編碼,該成員函數非常有用。
例子:
class SignalWaiter
{
private:
QMutexLocker locker;
public:
SignalWaiter(QMutex *mutex)
: locker(mutex)
{
}
void waitForSignal()
{
...
while (!signalled)
waitCondition.wait(locker.mutex());
...
}
};