如何在Qt中实现倒计时锁存?

时间:2016-07-13 21:31:45

标签: c++ qt synchronization

倒计时锁存器(a.k.a。CountDownLatch)是一个同步原语,可确保在销毁基元之前释放所有已使用的资源。它就像一个QSemaphore,但反向工作:我们希望阻止不获取资源,但要确保所有资源都已被释放。

在Qt中实现它的简单方法是什么?

1 个答案:

答案 0 :(得分:1)

这是一个利用QSemaphore的实现:

// 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}; }
};

要使用,请保留CountdownLatch::Locker的实例,同时希望锁定器保持阻塞状态。闩锁的析构函数将被阻塞,直到所有锁定器被摧毁。

#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;
}

实例a将一直存在,直到并发工作完成,即持续10秒。