大概說一下用法,例子:
QMutex mutex;
int number = 6;
void method1()
{
mutex.lock();
number *= 5;
number /= 4;
mutex.unlock();
}
void method2()
{
mutex.lock();
number *= 3;
number /= 2;
mutex.unlock();
}
用法大概可以總結為這樣:
QMutex mutex;
void method() {
mutex.lock();
// 你要做的騷操作
mutex.unlock()
}
作用:確保同一時間只有一個線程可以運行lock
與unlock
之間的內容。
其實這就是一個互斥鎖,經常用的地方是在訪問資源並作出修改的時候。這時候我們不希望有別的線程來同時訪問同一個資源,所以會給兩個線程要訪問資源的地方的代碼加上互斥鎖,這樣只有一個線程訪問完資源處理完並unlock
后,另一個線程才可以繼續執行。所以可以看到,QMutex
的lock
其實是阻塞式的,如果不能夠取得鎖那么沒有辦法繼續往下執行。如果想要弄成非阻塞式的,那么就要用tryLock
,並設置超時時長。但是這個就不展開說了。
例如,同時訪問一個全局變量number
:
int number = 6;
void method1()
{
number *= 5;
number /= 4;
}
void method2()
{
number *= 3;
number /= 2;
}
method1
和method2
分別是由兩個線程運行,正常情況下,我們的執行順序應該是這樣的:
// method1()
number *= 5; // number is now 30
number /= 4; // number is now 7
// method2()
number *= 3; // number is now 21
number /= 2; // number is now 10
調用順序不影響結果。
如果不加上互斥鎖,那么可能執行的順序是:
// Thread 1 calls method1()
number *= 5; // number is now 30
// Thread 2 calls method2().
//
// Most likely Thread 1 has been put to sleep by the operating
// system to allow Thread 2 to run.
number *= 3; // number is now 90
number /= 2; // number is now 45
// Thread 1 finishes executing.
number /= 4; // number is now 11, instead of 10
所以我們需要加上互斥鎖,確保當前只有一個進程訪問變量number
(可以看作是資源,其實原理都差不多):
QMutex mutex;
int number = 6;
void method1()
{
mutex.lock();
number *= 5;
number /= 4;
mutex.unlock();
}
void method2()
{
mutex.lock();
number *= 3;
number /= 2;
mutex.unlock();
}
這樣就可以確保只有一個線程完成了任務之后並且釋放掉互斥鎖之后,另一個線程才開始運行,保證了線程的完整運行和正確結果。
此外,可以通過成員函數bool QMutex::locked ()
來確定一個互斥量有沒有被lock
。如果已經被鎖定了返回true
,否則返回false
。