问题描述
倒计时锁存器(又名 CountDownLatch) 是一个同步原语,它确保在原语被销毁之前释放所有使用的资源.它就像一个 QSemaphore
,但反过来工作:我们想要阻塞不是为了获取资源,而是确保它们都被释放了.
A countdown latch (a.k.a. CountDownLatch) is a synchronization primitive that ensures that all of the used resources are released before the primitive is destroyed. It is like a QSemaphore
, but working in reverse: we want to block not to acquire a resource, but to ensure that all of them have been released.
在 Qt 中实现它的简单方法是什么?
What would be an easy way to implement it in Qt?
推荐答案
这是一个利用 QSemaphore
的实现:
Here's an implementation that leverages 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
的实例,同时您希望闩锁保持阻塞状态.锁存器的析构函数将一直阻塞,直到所有的锁存器都被销毁.
To use, keep an instance of CountdownLatch::Locker
while you want the latch to stay blocked. The latch's destructor will block until all locker's are destroyed.
#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 秒.
The instance a
will stay around until the concurrent worker is done, i.e. for 10 seconds.
这篇关于如何在 Qt 中实现倒计时锁存器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!