2013-08-22 24 views
0

我有兩個QMutex對象,我需要將它們都鎖定,erase()方法。但順序並不重要。
所以,現在我在等待一個QMutex處於解鎖狀態(QMutexLocker locker(&listMutex))狀態,並且比我等待另一個(QMutexLocker locker(&writeMutex))。
但它會更有效率地等待解鎖第一個互斥鎖。而不是等待另一個。等待時間會比較短。
怎麼可能實現這樣的行爲?
我應該創建額外的遞歸QMutex或QSemaphore,並將QMutex的狀態與這個新對象同步,而不是等待我的QMutex,而是等待這個新對象。
這應該可以工作,但也許沒有複製QMutex對象更容易一些嗎?等待第一個解鎖的QMutex如果QMutex很少

class MyQThread: 
    public: QThread 
{ 
    ... 
    QList<QString> list; 
    QString string; 
    QMutex listMutex; 
    QMutex writeMutex; 
} 

void MyQThread::erase() 
{ 
    QMutexLocker locker(&listMutex); 
    list.clear(); 
    QMutexLocker locker(&writeMutex); 
    string.clear(); 
} 

void MyQThread::run() 
{ 
    forever 
    { 
     listMutex.lock();    
     string = list.takeFirst(); 
     listMutex.unlock(); 

     writeMutex.lock(); 
     if(!string.isEmpty()) 
      ...//do something 
     writeMutex.unlock(); 
    } 
} 
+0

嗨凡特,只是爲了幫助澄清,你可以發佈您的代碼段爲您QMutexs :) –

+0

我添加了一個例子。 – Funt

回答

0

啊,好吧......

它略嫌麻煩,但你可以使用 「的tryLock()」,財產以後這樣的:

// You could add a loop around this until both are done... 

if (listMutex.tryLock()) 
{ 
    // list locked... do list stuff 
    listMutex.unlock(); 
} 
else if (writeMutex.tryLock()) 
{ 
    // writelocked... do writestuff 
    listMutex.unlock(); 
} 

注:的tryLock返回如果它實際上鎖定了互斥鎖,則爲true;否則爲false。

----編輯示例2:----

// Againm, you can stick a loop around this until you are done... 

if (listMutex.tryLock()) 
{ 
    // list locked... do list only stuff 
} 

if (writeMutex.tryLock()) 
{ 
    // writelocked... do write only stuff 
} 

if (listMutex.tryLock() && writeMutex.tryLock()) 
{ 
    // Both locked... do write and list stuff 
} 

// Make sure both are unlocked at the end 
listMutex.unlock(); 
listMutex.unlock(); 
+0

謝謝。但是,當兩個互斥鎖都被鎖定時,我還需要運行一些代碼。在這個例子中,只有一個互斥鎖可以鎖定,但不能同時鎖定。 – Funt

+0

但是,使用相同的想法是相當簡單的:)...我在底部添加了一個編輯給你一個線索:) –

+0

是的,但只有當它們都是免費的時,互斥鎖纔會被鎖定。在我的情況下,這個概率要低得多,因爲當一個人被鎖定而另一個人被解鎖時。因爲它們被鎖住了。這就是爲什麼最好的行爲是鎖定一個,然後等待第二個被解鎖......似乎不可能只使用QMutex。 – Funt

0

你可以做並行線程鎖定。請嘗試下面的例子(我沒有測試):

class BackgroundLocker : protected QThread { 
    protected: 
     QMutex& mutex; 
     void run() { 
      mutex.lock(); 
     } 
    public: 
     BackgroundLocker(QMutex& mutex): mutex(mutex) { 
      start(); 
     } 
     ~BackgroundLocker(QMutex& mutex) { 
      mutex.unlock(); 
     } 
     void waitLock() { 
      QThread::wait(); 
     } 
}; 

void MyQThread::erase() { 
    BackgroundLocker locker1(listMutex); 
    BackgroundLocker locker2(writeMutex); 
    locker1.waitLock(); 
    locker2.waitLock(); 
    list.clear(); 
    string.clear(); 
}