如果QMutex很少,则等待第一个未锁定的QMutex

时间:2013-08-22 06:42:19

标签: synchronization locking qthread unlock qmutex

我有两个QMutex对象,我需要同时锁定它们erase()方法。但序列并不重要 所以,现在我等待一个QMutex处于解锁(QMutexLocker locker(&listMutex))状态,而不是等待另一个(QMutexLocker locker(&writeMutex))。 但是等待第一个解锁的互斥锁会更有效率。而不是等待另一个。比等待时间更短 怎么可以实施这样的行为?
我应该创建额外的递归QMutex或QSemaphore并将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();
     }
}  

2 个答案:

答案 0 :(得分: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实际上锁定了互斥锁,则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();

答案 1 :(得分: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();
}