QSemaphore Class

QSemaphore 提供了一个通用的信号量. More...

头文件: #include <QSemaphore>
qmake: QT += core

Note: All functions in this class are thread-safe.

公有函数

QSemaphore(int n = 0)
~QSemaphore()
void acquire(int n = 1)
int available() const
void release(int n = 1)
bool tryAcquire(int n = 1)
bool tryAcquire(int n, int timeout)

详细描述

信号量是互斥量的泛化. 虽然互斥量只能锁定一次, 但可以多次获取信号. 信号量通常用于保护一定数量的相同资源.

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

  • acquire(n) 尝试获取 n resources. 个资源. 如果没有那么多可用资源, 调用将被阻塞, 直到能够获取.
  • release(n) 释放 n 个资源.

QSemaphore 有一个 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

信号量的一个典型应用场景, 是控制生产者线程和消费者线程对共享循环缓冲区的访问. Semaphores Example 展示了如何使用 QSemaphore 来解决这个问题.

一个非计算信号量的例子是在餐馆就餐. 用餐厅里的椅子数初始化信号量. 当人们到达时, 他们需要要一个座位. 入座后, available() 将减少. 当人们离开时, available() 会增加, 允许更多的人进入. 如果有一个 10 人的聚会, 但是餐馆只有 9 个座位, 那这 10 个人会等待空出位置. 但是如果此时有一个 4 人的聚会, 那么他们会入座 ( 将可用的座位减少到 5 个, 10 人聚会将等待更长时间).

另见 QSemaphoreReleaser, QMutex, QWaitCondition, QThread, Semaphores Example.

Member Function Documentation

QSemaphore::QSemaphore(int n = 0)

Creates a new semaphore and initializes the number of resources it guards to n (by default, 0).

See also release() and available().

QSemaphore::~QSemaphore()

Destroys the semaphore.

Warning: Destroying a semaphore that is in use may result in undefined behavior.

void QSemaphore::acquire(int n = 1)

Tries to acquire n resources guarded by the semaphore. If n > available(), this call will block until enough resources are available.

See also release(), available(), and tryAcquire().

int QSemaphore::available() const

Returns the number of resources currently available to the semaphore. This number can never be negative.

See also acquire() and release().

void QSemaphore::release(int n = 1)

Releases n resources guarded by the semaphore.

This function can be used to "create" resources as well. For example:

 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 is a RAII wrapper around this function.

See also acquire(), available(), and QSemaphoreReleaser.

bool QSemaphore::tryAcquire(int n = 1)

Tries to acquire n resources guarded by the semaphore and returns true on success. If available() < n, this call immediately returns false without acquiring any resources.

Example:

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

See also acquire().

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

Tries to acquire n resources guarded by the semaphore and returns true on success. If available() < n, this call will wait for at most timeout milliseconds for resources to become available.

Note: Passing a negative number as the timeout is equivalent to calling acquire(), i.e. this function will wait forever for resources to become available if timeout is negative.

Example:

 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

See also acquire().