2013-08-22 25 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(); 
}