2016-07-13 4 views
1

Ein Countdown-Latch (a.k.a. CountDownLatch) ist ein Synchronisations-Primitiv, das sicherstellt, dass alle verwendeten Ressourcen freigegeben werden, bevor das Primitiv zerstört wird. Es ist wie ein QSemaphore, funktioniert aber in umgekehrter Reihenfolge: Wir möchten blockieren, um keine Ressource zu erhalten, sondern um sicherzustellen, dass alle freigegeben wurden.Wie implementiert man ein Countdown-Latch in Qt?

Was wäre eine einfache Möglichkeit, es in Qt zu implementieren?

Antwort

1

Hier ist eine Implementierung, die QSemaphore nutzt:

// https://github.com/KubaO/stackoverflown/tree/master/questions/countdown-latch-38362044 
#include <climits> 
#include <QSemaphore> 

class CountDownLatch { 
    Q_DISABLE_COPY(CountDownLatch) 
    QSemaphore m_sem{INT_MAX}; 
public: 
    CountDownLatch() {} 
    ~CountDownLatch() { 
    m_sem.acquire(INT_MAX); 
    m_sem.release(INT_MAX); 
    } 
    class Locker { 
    CountDownLatch * sem; 
    public: 
    Locker(const Locker & other) : sem{other.sem} { sem->m_sem.acquire(); } 
    Locker(Locker && other) : sem{other.sem} { other.sem = nullptr; } 
    Locker(CountDownLatch * sem) : sem{sem} { sem->m_sem.acquire(); } 
    ~Locker() { if (sem) sem->m_sem.release(); } 
    }; 
    Locker lock() { return Locker{this}; } 
}; 

zu verwenden, um eine Instanz von CountdownLatch::Locker zu halten, während Sie die Verriegelung wollen gesperrt bleiben. Der Destruktor des Latch wird blockieren, bis alle Schließfächer zerstört sind.

#include <QtConcurrent> 

struct MyClass { 
    CountDownLatch m_latch; 
    MyClass() { 
    auto lock = m_latch.lock(); // must be taken here 
    QtConcurrent::run([this, lock]{ 
     // DON'T lock here, you'll have a race! 
     QThread::sleep(10); 
    }); 
    } 
}; 

int main() { 
    MyClass a; 
} 

Die Instanz a rund bleiben wird, bis der Arbeiter gleichzeitig für 10 Sekunden durchgeführt wird, das heißt.

Verwandte Themen