QSemaphore 类

QSemaphore 类提供了一个通用的计数信号量。更多...

头文件 #include <QSemaphore>
CMakefind_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core)
qmakeQT += core

注意: 此类中所有函数都是 线程安全的

公共函数

QSemaphore(int n = 0)
~QSemaphore()
voidacquire(int n = 1)
intavailable() const
voidrelease(int n = 1)
booltryAcquire(int n = 1)
booltryAcquire(int n, int timeout)
(since 6.6) booltryAcquire(int n, QDeadlineTimer timer)
(since 6.3) booltryAcquire(int n, std::chrono::duration<Rep, Period> timeout)
(since 6.3) booltry_acquire()
(since 6.3) booltry_acquire_for(const std::chrono::duration<Rep, Period> &timeout)
(since 6.3) booltry_acquire_until(const std::chrono::time_point<Clock, Duration> &tp)

详细说明

信号量是互斥量的泛化。互斥量只能锁定一次,而信号量可以被重复获取。信号量通常用于保护一定数量的相同资源。

信号量支持两个基本操作,acquire() 和 release()

  • acquire(n) 尝试获取 n 个资源。如果没有这么多的资源可用,调用将阻塞直到这种情况发生。
  • release(n) 释放 n 个资源。

还有一个 tryAcquire() 函数,如果不能获取资源,它将立即返回,以及一个 available() 函数,在任何时候都返回可用的资源数量。

示例

QSemaphore sem(5);      // sem.available() == 5

sem.acquire(3);         // sem.available() == 2
sem.acquire(2);         // sem.available() == 0
sem.release(5);         // sem.available() == 5
sem.release(5);         // sem.available() == 10

sem.tryAcquire(1);      // sem.available() == 9, returns true
sem.tryAcquire(250);    // sem.available() == 9, returns false

信号量的典型应用是控制生产者线程和消费者线程共享的循环缓冲区的访问。 使用信号量的生产者和消费者 示例展示了如何使用 QSemaphore 解决此问题。

一个非计算示例中的信号量,可以是在餐馆用餐。信号量初始化时与餐馆中的椅子数量相同。当人们到达时,他们需要座位。当座位被填满时,available() 将递减。当人们离开时,available() 将递增,允许更多人进入。如果有一组10人想要坐下,但只有9个座位,这些人将等待,而一组4人将首先坐下(此时可获得座位数为5,使得10人的组等待时间更长)。

另请参阅QSemaphoreReleaserQMutexQWaitConditionQThread使用信号量的生产者和消费者

成员函数文档

[显式] QSemaphore::QSemaphore(int n = 0)

创建一个新的信号量,将其保护的资源数量初始化为 n(默认为 0)。

另请参阅release() 和 available

[noexcept] QSemaphore::~QSemaphore()

销毁信号量。

警告:销毁正在使用的信号量可能会导致未定义的行为。

void QSemaphore::acquire(int n = 1)

尝试获取信号量保护的 n 资源。如果 n > available(),则此调用将阻塞,直到足够的资源可用。

另请参阅releaseavailabletryAcquire

int QSemaphore::available() const

返回信号量当前可用的资源数量。此数字永远不会是负数。

另请参阅acquirerelease

void QSemaphore::release(int n = 1)

释放信号量保护的 n 资源。

此函数可用于“创建”资源。例如

QSemaphore sem(5);      // a semaphore that guards 5 resources
sem.acquire(5);         // acquire all 5 resources
sem.release(5);         // release the 5 resources
sem.release(10);        // "create" 10 new resources

QSemaphoreReleaser 是围绕此函数的 RAII 封装。

另请参阅acquireavailableQSemaphoreReleaser

bool QSemaphore::tryAcquire(int n = 1)

尝试获取信号量保护的 n 资源,并在成功时返回 true。如果 available() < n,则此调用将立即返回 false,而不会获取任何资源。

示例

QSemaphore sem(5);      // sem.available() == 5
sem.tryAcquire(250);    // sem.available() == 5, returns false
sem.tryAcquire(3);      // sem.available() == 2, returns true

另请参阅acquire

bool QSemaphore::tryAcquire(int n, int timeout)

尝试获取由信号量保护的 n 资源,并在成功时返回 true。如果 available() < n,则此调用将等待最多 timeout 毫秒,直到资源可用。

注意:将负数传递给 timeout 等同于调用 acquire(),即如果 timeout 为负,则此函数将无限期地等待资源可用。

示例

QSemaphore sem(5);            // sem.available() == 5
sem.tryAcquire(250, 1000);    // sem.available() == 5, waits 1000 milliseconds and returns false
sem.tryAcquire(3, 30000);     // sem.available() == 2, returns true without waiting

另请参阅acquire

[since 6.6] bool QSemaphore::tryAcquire(int n, QDeadlineTimer timer)

尝试获取由信号量保护的 n 资源,并在成功时返回 true。如果 available() < n,则此调用将等待直到 timer 到期,以等待资源可用。

示例

QSemaphore sem(5);                          // sem.available() == 5
sem.tryAcquire(250, QDeadlineTimer(1000));  // sem.available() == 5, waits 1000 milliseconds and returns false
sem.tryAcquire(3, QDeadlineTimer(30s));     // sem.available() == 2, returns true without waiting

此函数自 Qt 6.6 版本开始引入。

另请参阅acquire

[since 6.3] 模板 <typename Rep, typename Period> bool QSemaphore::tryAcquire(int n, std::chrono::duration<Rep, Period> timeout)

这是一个重载函数。

此函数自 Qt 6.3 版本开始引入。

[noexcept, since 6.3] bool QSemaphore::try_acquire()

此函数提供 std::counting_semaphore 兼容性。

它等价于调用 tryAcquire(1),其中函数在成功获取资源时返回 true

此函数自 Qt 6.3 版本开始引入。

另请参阅tryAcquire()、try_acquire_for() 和 try_acquire_until()。

[since 6.3] 模板 <typename Rep, typename Period> bool QSemaphore::try_acquire_for(const std::chrono::duration<Rep, Period> &timeout)

此函数提供 std::counting_semaphore 兼容性。

它等价于调用 tryAcquire(1, timeout),其中调用在给定的 timeout 值时超时。函数在成功获取资源时返回 true

此函数自 Qt 6.3 版本开始引入。

另请参阅tryAcquire()、try_acquire() 和 try_acquire_until()。

[since 6.3] 模板 <typename Clock, typename Duration> bool QSemaphore::try_acquire_until(const std::chrono::time_point<Clock, Duration> &tp)

此函数提供 std::counting_semaphore 兼容性。

它等价于调用 tryAcquire(1, tp - Clock::now()),这意味着记录了 tp (时间点),在等待期间忽略了 Clock 的调整。函数在成功获取资源时返回 true

此函数自 Qt 6.3 版本开始引入。

另请参阅tryAcquire()、try_acquire() 和 try_acquire_for()。

版权所有© 2024 The Qt Company Ltd。本文件包含的文档贡献均为各自所有者的版权。本文件中的文档遵循由自由软件基金会发布的GNU自由文档许可第1.3版的条款。Qt以及相应的标志为芬兰及/或其他国家/地区The Qt Company Ltd的商标。所有其他商标均为各自所有者的财产。