2011-12-06 66 views
1

在Linux下qt 4.7.4使用gcc 4.4.3 下面的代碼編譯得很好,沒有運行時錯誤。QReadWriteLock遞歸模式不工作

class TestThread: public QThread { 
    private: 
     QReadWriteLock mutex; 

    public: 
    bool mStop; 

    TestThread(): mutex(QReadWriteLock::NonRecursive),mStop(false) {} 
    void run() { 
     while(!mStop) { 
     mutex.lockForRead();   
     qDebug() << "Tread running"; 
     msleep(100);   
     } 
    } 
}; 

鎖被同一​​個線程多次鎖定,沒有任何反應。根據手冊http://doc.qt.io/archives/qt-4.7/qreadwritelock.html

該鎖應該只能由同一個線程鎖定一次。這是一些嚴重的錯誤還是我誤解了手冊?

回覆Chris:在NonRecursive中也必須解鎖多次,如果一個解鎖被註釋掉,下面的代碼永遠不會打印「Writing」。

class TestThread: public QThread { 
    private: 
    QReadWriteLock mutex; 

    public: 
    TestThread(): mutex(QReadWriteLock::NonRecursive){} 
    void run() { 
     mutex.lockForRead(); 
     mutex.lockForRead(); 
     qDebug() << "Tread running"; 
     //mutex.unlock(); 
     mutex.unlock(); 
     mutex.lockForWrite(); 
     qDebug() << "Writing"; 
     mutex.unlock(); 
     msleep(50); 
    } 
}; 


int main(int argc, char *argv[]) { 
    TestThread myThread; 

    myThread.start(); 
    usleep(500000); 
    myThread.terminate(); 
} 
+0

是的你是對的,行爲有點混亂。我將不得不做更多的挖掘來弄清楚那裏發生了什麼。 – Chris

回答

0

我想QReadWriteLock::NonRecursive模式隻影響寫鎖。

嘗試從同一個線程獲取兩次非遞歸模式的寫入鎖,我想你會得到你期望的行爲。

+0

寫入鎖定應始終只能獲得一次。如果不是的話,你會遇到嚴重的麻煩 – Martin

+1

我知道,我只是想提一下,在'NonRecursive'模式下獲取讀鎖不會被阻塞的原因可能是「QReadWriteLock :: NonRecursive模式隻影響獲取寫鎖」。遞歸地獲得一個寫鎖(即在同一個線程中多次)確實是有意義的。假設你有一個函數調用第二個函數,並且都想要寫入鎖定。 –

+0

好點。沒有什麼明確的手冊,但至少這是有道理的;-) – Martin

2

我終於找到了主要區別。當QReadWritelock被聲明爲遞歸時,來自一個線程的Readlock只能算作一個鎖。因此,在同一個線程中讀取的連續鎖定不會被等待的寫入鎖定阻塞。當鎖被聲明爲非遞歸時,這可能發生並導致非常嚴重的死鎖。

+0

我發現這是困難的方式 – Srikan