本页内容

QReadWriteLock Class

QReadWriteLock 类提供了读写锁定功能。更多内容...

头文件: #include <QReadWriteLock>
CMake: find_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core)
qmake: QT += core
继承自: QBasicReadWriteLock

注意:该类中的所有函数均是线程安全的。

公共类型

enum RecursionMode { Recursive, NonRecursive }

公共函数

QReadWriteLock(QReadWriteLock::RecursionMode recursionMode = NonRecursive)
~QReadWriteLock()
void lockForRead()
void lockForWrite()
bool tryLockForRead(int timeout)
(since 6.6) bool tryLockForRead(QDeadlineTimer timeout = {})
bool tryLockForWrite(int timeout)
(since 6.6) bool tryLockForWrite(QDeadlineTimer timeout = {})
void unlock()

详细说明

读写锁是一种用于保护可被读写访问的资源的同步工具。如果您希望允许多个线程同时进行只读访问,但一旦有一个线程想要向该资源写入数据,所有其他线程都必须被阻塞,直到写入操作完成,那么这种类型的锁就非常有用。

在许多情况下,QReadWriteLock 是QMutex 的直接竞争对手。如果存在大量并发读取,而写入操作却很少发生,那么 QReadWriteLock 是一个不错的选择。

示例:

QReadWriteLock lock;

void ReaderThread::run()
{
    //...
    lock.lockForRead();
    read_file();
    lock.unlock();
    //...
}

void WriterThread::run()
{
    //...
    lock.lockForWrite();
    write_file();
    lock.unlock();
    //...
}

为了确保写入线程不会被读取线程无限期阻塞,如果存在被阻塞的写入线程正在等待访问,则尝试获取锁的读取线程将无法成功,即使当前锁仅被其他读取线程访问。此外,如果锁正被一个写入线程访问,而另一个写入线程加入,则该写入线程将优先于任何可能也在等待的读取线程。

与QMutex 类似,当使用QReadWriteLock::Recursive (如QReadWriteLock::RecursionMode 所示)构造QReadWriteLock时,同一线程可以对其进行递归锁定。在这种情况下,必须调用unlock()的次数与调用lockForWrite()或lockForRead()的次数相同。 请注意,在尝试递归锁定时,无法更改锁的类型,即无法在一个已获取写锁的线程中获取读锁(反之亦然)。

另请参阅 QReadLocker 、QWriteLocker 、QMutex 以及QSemaphore 。

成员类型文档

enum QReadWriteLock::RecursionMode

常数值描述
QReadWriteLock::Recursive1在此模式下,一个线程可以多次锁定同一个QReadWriteLock 。除非已调用相应次数的unlock()方法,否则QReadWriteLock 将不会被解锁。
QReadWriteLock::NonRecursive0在此模式下,一个线程只能锁定同一QReadWriteLock 一次。

另请参阅 QReadWriteLock()。

成员函数文档

[explicit] QReadWriteLock::QReadWriteLock(QReadWriteLock::RecursionMode recursionMode = NonRecursive)

在指定的recursionMode 中构建一个QReadWriteLock对象。

默认递归模式为NonRecursive 。

另请参阅 lockForRead()、lockForWrite() 和RecursionMode 。

[noexcept] QReadWriteLock::~QReadWriteLock()

销毁QReadWriteLock 对象。

警告:销毁 正在使用的读写锁可能会导致未定义的行为。

void QReadWriteLock::lockForRead()

将锁设为只读锁。如果另一个线程已将该锁设为写锁,则此函数将阻塞当前线程。

如果线程已处于写锁状态,则无法进行读锁操作。

另请参阅 unlock()、lockForWrite() 和tryLockForRead()。

void QReadWriteLock::lockForWrite()

将锁锁定为写锁。如果另一个线程(包括当前线程)已将该锁锁定为读锁或写锁,则此函数将阻塞当前线程(除非该锁是使用QReadWriteLock::Recursive 模式创建的)。

如果线程已以读模式锁定,则无法以写模式锁定。

另请参阅 unlock()、lockForRead() 和tryLockForWrite()。

bool QReadWriteLock::tryLockForRead(int timeout)

尝试获取读锁。如果成功获取锁,该函数返回true ;否则返回false 。如果另一个线程已获取写锁,该函数将最多等待timeout 毫秒,直到锁可用。

注意:将负数作为timeout 参数传递等同于调用lockForRead(),即当timeout 为负数时,该函数将无限期等待,直到能够以读模式获取锁。

如果已获得锁,则必须先使用unlock() 解锁,另一个线程才能成功以写入方式锁定该锁。

如果线程已经以写入方式锁定,则无法以读取方式锁定。

另请参阅 unlock() 和lockForRead()。

[since 6.6] bool QReadWriteLock::tryLockForRead(QDeadlineTimer timeout = {})

尝试获取读锁。如果成功获取锁,该函数返回true ;否则返回false 。如果另一个线程已获取写锁,该函数将等待直至timeout 超时,锁才可被释放。

如果成功获取了锁,必须先使用unlock() 解锁,其他线程才能成功以写入方式锁定该锁。

如果线程已经为写操作加了锁,则无法为读操作加锁。

这是一个重载函数。

该函数在 Qt 6.6 中引入。

另请参阅 unlock() 和lockForRead()。

bool QReadWriteLock::tryLockForWrite(int timeout)

尝试获取写锁。如果成功获取锁,该函数返回true ;否则返回false 。如果另一个线程已获取读锁或写锁,该函数将最多等待timeout 毫秒,直到锁可用。

注意:将负数作为timeout 参数传递等同于调用lockForWrite(),即当timeout 为负值时,该函数将无限期等待,直到能够以写入方式锁定该锁。

如果已获取锁,则必须先使用unlock() 解锁,其他线程才能成功锁定该锁。

如果线程已经以读方式加锁,则无法以写方式加锁。

另请参见 unlock() 和lockForWrite()。

[since 6.6] bool QReadWriteLock::tryLockForWrite(QDeadlineTimer timeout = {})

尝试获取写锁。如果成功获取锁,该函数返回true ;否则返回false 。如果另一个线程已获取读锁或写锁,该函数将等待直至timeout 超时,锁才可被释放。

如果成功获取了锁,必须先使用unlock() 解锁,其他线程才能成功锁定该锁。

如果线程已经以读模式锁定,则无法以写模式锁定。

这是一个重载函数。

该函数在 Qt 6.6 中引入。

另请参阅 unlock() 和lockForWrite()。

void QReadWriteLock::unlock()

解锁该锁。

尝试解锁未上锁的锁将引发错误,并导致程序终止。

另请参阅 lockForRead()、lockForWrite()、tryLockForRead() 和tryLockForWrite()。

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.