QSemaphore Class
The QSemaphore class provides a general counting semaphore. More...
Header: | #include <QSemaphore> |
CMake: | find_package(Qt6 REQUIRED COMPONENTS Core) target_link_libraries(mytarget PRIVATE Qt6::Core) |
qmake: | QT += core |
- List of all members, including inherited members
- QSemaphore is part of Threading Classes.
Note: All functions in this class are thread-safe.
Public Functions
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) |
(since 6.6) bool | tryAcquire(int n, QDeadlineTimer timer) |
(since 6.3) bool | tryAcquire(int n, std::chrono::duration<Rep, Period> timeout) |
(since 6.3) bool | try_acquire() |
(since 6.3) bool | try_acquire_for(const std::chrono::duration<Rep, Period> &timeout) |
(since 6.3) bool | try_acquire_until(const std::chrono::time_point<Clock, Duration> &tp) |
Detailed Description
A semaphore is a generalization of a mutex. While a mutex can only be locked once, it's possible to acquire a semaphore multiple times. Semaphores are typically used to protect a certain number of identical resources.
Semaphores support two fundamental operations, acquire() and release():
- acquire(n) tries to acquire n resources. If there aren't that many resources available, the call will block until this is the case.
- release(n) releases n resources.
There's also a tryAcquire() function that returns immediately if it cannot acquire the resources, and an available() function that returns the number of available resources at any time.
Example:
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
A typical application of semaphores is for controlling access to a circular buffer shared by a producer thread and a consumer thread. The Producer and Consumer using Semaphores example shows how to use QSemaphore to solve that problem.
A non-computing example of a semaphore would be dining at a restaurant. A semaphore is initialized with the number of chairs in the restaurant. As people arrive, they want a seat. As seats are filled, available() is decremented. As people leave, the available() is incremented, allowing more people to enter. If a party of 10 people want to be seated, but there are only 9 seats, those 10 people will wait, but a party of 4 people would be seated (taking the available seats to 5, making the party of 10 people wait longer).
See also QSemaphoreReleaser, QMutex, QWaitCondition, QThread, and Producer and Consumer using Semaphores.
Member Function Documentation
[explicit]
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().
[noexcept]
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().
[since 6.6]
bool QSemaphore::tryAcquire(int n, QDeadlineTimer timer)
Tries to acquire n
resources guarded by the semaphore and returns true
on success. If available() < n, this call will wait until timer expires for resources to become available.
Example:
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
This function was introduced in Qt 6.6.
See also acquire().
[since 6.3]
template <typename Rep, typename Period> bool QSemaphore::tryAcquire(int n, std::chrono::duration<Rep, Period> timeout)
This is an overloaded function.
This function was introduced in Qt 6.3.
[noexcept, since 6.3]
bool QSemaphore::try_acquire()
This function is provided for std::counting_semaphore
compatibility.
It is equivalent to calling tryAcquire(1)
, where the function returns true
on acquiring the resource successfully.
This function was introduced in Qt 6.3.
See also tryAcquire(), try_acquire_for(), and try_acquire_until().
[since 6.3]
template <typename Rep, typename Period> bool QSemaphore::try_acquire_for(const std::chrono::duration<Rep, Period> &timeout)
This function is provided for std::counting_semaphore
compatibility.
It is equivalent to calling tryAcquire(1, timeout)
, where the call times out on the given timeout value. The function returns true
on acquiring the resource successfully.
This function was introduced in Qt 6.3.
See also tryAcquire(), try_acquire(), and try_acquire_until().
[since 6.3]
template <typename Clock, typename Duration> bool QSemaphore::try_acquire_until(const std::chrono::time_point<Clock, Duration> &tp)
This function is provided for std::counting_semaphore
compatibility.
It is equivalent to calling tryAcquire(1, tp - Clock::now())
, which means that the tp (time point) is recorded, ignoring the adjustments to Clock
while waiting. The function returns true
on acquiring the resource successfully.
This function was introduced in Qt 6.3.
See also tryAcquire(), try_acquire(), and try_acquire_for().