- Qt 6.10
- Qt Core
- C++ Classes
- QRecursiveMutex
- Qt 6.10.2 Reference Documentation

# QRecursiveMutex Class

The QRecursiveMutex class provides access serialization between threads. More...

Header: | `#include <QRecursiveMutex>`
CMake: | `find_package(Qt6 REQUIRED COMPONENTS Core)` `target_link_libraries(mytarget PRIVATE Qt6::Core)`
qmake: | `QT += core`

- List of all members, including inherited members

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

## Public Functions

| QRecursiveMutex()
| ~QRecursiveMutex()
void | lock()
`(since 6.6)` bool | tryLock(QDeadlineTimer timeout = {})
bool | tryLock(int timeout)
bool | try_lock()
bool | try_lock_for(std::chrono::duration<Rep, Period> duration)
bool | try_lock_until(std::chrono::time_point<Clock, Duration> timePoint)
void | unlock()

## Detailed Description

The QRecursiveMutex class is a mutex, like QMutex, with which it is API-compatible. It differs from QMutex by accepting lock() calls from the same thread any number of times. QMutex would deadlock in this situation.

QRecursiveMutex is much more expensive to construct and operate on, so use a plain QMutex whenever you can. Sometimes, one public function, however, calls another public function, and they both need to lock the same mutex. In this case, you have two options:

- Factor the code that needs mutex protection into private functions, which assume that the mutex is held when they are called, and lock a plain QMutex in the public functions before you call the private implementation ones.
- Or use a recursive mutex, so it doesn't matter that the first public function has already locked the mutex when the second one wishes to do so.

See also QMutex, QMutexLocker, QReadWriteLock, QSemaphore, and QWaitCondition.

## Member Function Documentation

### `[constexpr noexcept]` QRecursiveMutex::QRecursiveMutex()

Constructs a new recursive mutex. The mutex is created in an unlocked state.

See also lock() and unlock().

### `[noexcept]` QRecursiveMutex::~QRecursiveMutex()

Destroys the mutex.

Warning: Destroying a locked mutex may result in undefined behavior.

### `[noexcept(...)]` void QRecursiveMutex::lock()

Locks the mutex. If another thread has locked the mutex then this call will block until that thread has unlocked it.

Calling this function multiple times on the same mutex from the same thread is allowed.

Note: This function is noexcept when `LockIsNoexcept` is `true`.

See also unlock().

### `[noexcept(...), since 6.6]` bool QRecursiveMutex::tryLock(QDeadlineTimer timeout = {})

Attempts to lock the mutex. This function returns `true` if the lock was obtained; otherwise it returns `false`. If another thread has locked the mutex, this function will wait until timeout expires for the mutex to become available.

If the lock was obtained, the mutex must be unlocked with unlock() before another thread can successfully lock it.

Calling this function multiple times on the same mutex from the same thread is allowed.

This function was introduced in Qt 6.6.

Note: This function is noexcept when `LockIsNoexcept` is `true`.

See also lock() and unlock().

### `[noexcept(...)]` bool QRecursiveMutex::tryLock(int timeout)

Attempts to lock the mutex. This function returns `true` if the lock was obtained; otherwise it returns `false`. If another thread has locked the mutex, this function will wait for at most timeout milliseconds for the mutex to become available.

Note: Passing a negative number as the timeout is equivalent to calling lock(), i.e. this function will wait forever until mutex can be locked if timeout is negative.

If the lock was obtained, the mutex must be unlocked with unlock() before another thread can successfully lock it.

Calling this function multiple times on the same mutex from the same thread is allowed.

Note: This function is noexcept when `LockIsNoexcept` is `true`.

See also lock() and unlock().

### `[noexcept(...)]` bool QRecursiveMutex::try_lock()

Attempts to lock the mutex. This function returns `true` if the lock was obtained; otherwise it returns `false`.

This function is provided for compatibility with the Standard Library concept `Lockable`. It is equivalent to tryLock().

Note: This function is noexcept when `LockIsNoexcept` is `true`.

### template <typename Rep, typename Period> bool QRecursiveMutex::try_lock_for(std::chrono::duration<Rep, Period> duration)

Attempts to lock the mutex. This function returns `true` if the lock was obtained; otherwise it returns `false`. If another thread has locked the mutex, this function will wait for at least duration for the mutex to become available.

Note: Passing a negative duration as the duration is equivalent to calling try_lock(). This behavior differs from tryLock().

If the lock was obtained, the mutex must be unlocked with unlock() before another thread can successfully lock it.

Calling this function multiple times on the same mutex from the same thread is allowed.

See also lock() and unlock().

### template <typename Clock, typename Duration> bool QRecursiveMutex::try_lock_until(std::chrono::time_point<Clock, Duration> timePoint)

Attempts to lock the mutex. This function returns `true` if the lock was obtained; otherwise it returns `false`. If another thread has locked the mutex, this function will wait at least until timePoint for the mutex to become available.

Note: Passing a timePoint which has already passed is equivalent to calling try_lock(). This behavior differs from tryLock().

If the lock was obtained, the mutex must be unlocked with unlock() before another thread can successfully lock it.

Calling this function multiple times on the same mutex from the same thread is allowed.

See also lock() and unlock().

### `[noexcept]` void QRecursiveMutex::unlock()

Unlocks the mutex. Attempting to unlock a mutex in a different thread to the one that locked it results in an error. Unlocking a mutex that is not locked results in undefined behavior.

See also lock().