2013-08-22 3 views
0

두 개의 QMutex 객체가 있는데 두 객체를 모두 잠글 필요가 있습니다 (erase() 메서드). 그러나 그 순서는 중요하지 않습니다.
하나의 QMutex가 잠금 해제 (QMutexLocker locker(&listMutex)) 상태이고 다른 것을 기다리는 것보다 (QMutexLocker locker(&writeMutex)) 기다리는 중입니다.
하지만 잠금 해제 된 뮤텍스를 기다리는 것이 더 효율적입니다. 그리고 다른 하나를 기다리는 것보다. 대기 시간보다 짧아집니다.
어떻게 이러한 동작을 구현할 수 있습니까?
재귀 QMutex 또는 QSemaphore를 다시 만들고 QMutex와이 새 개체의 상태를 동기화해야하며 QMutex가 아니라이 새 개체를 기다려야합니다.
그래도 작동하지만 어쩌면 QMutex 객체를 복제하지 않고 더 쉬운 방법이 있을까요?QMutex가 거의없는 경우 잠기지 않은 QMutex를 기다리는 중

// 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 반환됩니다

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

안녕 Funt : –

+0

내가 예를 추가 한 다음 예를 (내가 그것을 테스트하지 않았다) 시도하십시오. – Funt

답변

0

아, 괜찮아 ... 바이올린의

조금,하지만 당신은 "설정된 tryLock()"이 같은 뭔가를해야만 사용할 수 있습니다 뮤텍스를 acutally 잠근 경우 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

당신은 병렬 스레드에서 잠금을 할 수 있습니다. 당신이 당신의 QMutexs에 대한 귀하의 코드를 게시 할 수있는, 단지 명확하게하기 위해,

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(); 
}