QMutex Class
QMutex 类提供线程间的访问序列化。更多
头文件: | #include <QMutex> |
CMake: | find_package(Qt6 REQUIRED COMPONENTS Core) target_link_libraries(mytarget PRIVATE Qt6::Core) |
qmake: | QT += core |
- 所有成员(包括继承成员)的列表
- QMutex 是线程类的一部分。
注意:该类中的所有函数都是线程安全的。
公共函数
QMutex() | |
~QMutex() | |
void | lock() |
(since 6.6) bool | tryLock(QDeadlineTimer timer) |
bool | tryLock(int timeout) |
bool | tryLock() |
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() |
详细说明
QMutex 的作用是保护对象、数据结构或代码段,使同一时间只有一个线程可以访问(这类似于 Javasynchronized
关键字)。通常情况下,最好使用带有QMutexLocker 的互斥器,因为这样可以轻松确保锁定和解锁执行的一致性。
例如,有一个方法要在两行上向用户打印一条消息:
int number = 6; void method1() { number *= 5; number /= 4; } void method2() { number *= 3; number /= 2; }
如果连续调用这两个方法,会发生以下情况:
// method1() number *= 5; // number is now 30 number /= 4; // number is now 7 // method2() number *= 3; // number is now 21 number /= 2; // number is now 10
如果这两个方法同时被两个线程调用,那么可能会出现以下情况:
// Thread 1 calls method1() number *= 5; // number is now 30 // Thread 2 calls method2(). // // Most likely Thread 1 has been put to sleep by the operating // system to allow Thread 2 to run. number *= 3; // number is now 90 number /= 2; // number is now 45 // Thread 1 finishes executing. number /= 4; // number is now 11, instead of 10
如果我们添加一个互斥,就会得到我们想要的结果:
QMutex mutex; int number = 6; void method1() { mutex.lock(); number *= 5; number /= 4; mutex.unlock(); } void method2() { mutex.lock(); number *= 3; number /= 2; mutex.unlock(); }
那么在任何给定时间内,只有一个线程可以修改number
,结果是正确的。当然,这只是一个微不足道的例子,但它适用于任何其他需要按特定顺序进行操作的情况。
在一个线程中调用lock() 时,其他试图在同一位置调用lock() 的线程将阻塞,直到获得锁的线程调用unlock() 。lock() 的非阻塞替代方法是tryLock()。
QMutex 已经过优化,在非指定情况下速度很快。如果该互斥项上没有竞争,它就不会分配内存。它的构造和销毁几乎没有任何开销,这意味着作为其他类的一部分,拥有许多互斥器也没有问题。
另请参见 QRecursiveMutex,QMutexLocker,QReadWriteLock,QSemaphore 和QWaitCondition 。
成员函数文档
[constexpr noexcept]
QMutex::QMutex()
构造一个新的互斥体。互斥以解锁状态创建。
[noexcept]
QMutex::~QMutex()
销毁互斥。
警告 销毁锁定的互斥可能导致未定义的行为。
[noexcept(...)]
void QMutex::lock()
锁定互斥。如果另一个线程锁定了该互斥项,则此调用将阻塞,直到该线程解锁为止。
同一线程对同一互斥项多次调用此函数将导致死锁。
注意: 当FutexAlwaysAvailable
为true
时,此函数为 noexcept。
另请参阅 unlock() 。
[noexcept(...), since 6.6]
bool QMutex::tryLock(QDeadlineTimer timer)
尝试锁定互斥。如果锁定成功,则返回true
;否则返回false
。如果另一个线程锁定了互斥项,该函数将等待直到timer 过期,互斥项才能可用。
如果已获得锁,则必须先使用unlock() 解锁互斥体,然后另一个线程才能成功锁定它。
同一线程对同一互斥项多次调用此函数将导致死锁。
此函数在 Qt 6.6 中引入。
注意: 当FutexAlwaysAvailable
为true
时,此函数为 noexcept。
[noexcept(...)]
bool QMutex::tryLock(int timeout)
尝试锁定互斥。如果锁定成功,则返回true
;否则返回false
。如果另一个线程锁定了互斥项,该函数将最多等待timeout 毫秒,直到互斥项可用。
注意:如果timeout 为负数,则等同于调用lock() ,也就是说,如果timeout 为负数,则此函数将永远等待互斥体被锁定。
如果已获得锁定,则必须使用unlock() 解锁该互斥项,然后另一个线程才能成功锁定它。
同一线程对同一互斥项多次调用此函数将导致死锁。
注意: 当FutexAlwaysAvailable
为true
时,此函数为 noexcept。
[noexcept]
bool QMutex::tryLock()
这是一个重载函数。
尝试锁定互斥。如果锁定成功,则返回true
;否则返回false
。
如果获得了锁,则必须使用unlock() 解锁该互斥项,其他线程才能成功锁定它。
同一线程对同一互斥多次调用此函数将导致死锁。
[noexcept]
bool QMutex::try_lock()
尝试锁定互斥。如果获得锁定,则返回true
;否则返回false
。
提供该函数是为了与标准库概念Lockable
兼容。它等同于tryLock()。
template <typename Rep, typename Period> bool QMutex::try_lock_for(std::chrono::duration<Rep, Period> duration)
尝试锁定互斥。如果锁定成功,则返回true
;否则返回false
。如果另一个线程锁定了互斥项,则该函数将至少等待duration 才能使互斥项可用。
注意:传递负持续时间作为duration 相当于调用try_lock() 。此行为与tryLock() 不同。
如果已获得锁,则必须先使用unlock() 解锁互斥,然后另一个线程才能成功锁定它。
同一线程对同一互斥多次调用该函数将导致死锁。
template <typename Clock, typename Duration> bool QMutex::try_lock_until(std::chrono::time_point<Clock, Duration> timePoint)
尝试锁定互斥。如果锁定成功,则返回true
;否则返回false
。如果另一个线程锁定了互斥项,则该函数将至少等待到timePoint ,直到互斥项可用。
注意:传递已通过的timePoint 等同于调用try_lock() 。此行为与tryLock() 不同。
如果已获得锁,则必须先用unlock() 解锁互斥项,然后另一个线程才能成功锁定它。
同一线程对同一互斥多次调用该函数将导致死锁。
[noexcept]
void QMutex::unlock()
解锁互斥。试图在不同于锁定该互斥项的线程中解锁互斥项会导致错误。解锁未锁定的互斥项会导致未定义的行为。
另请参阅 lock().
© 2025 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.