QMutex类

QMutex类提供线程间的访问序列化。 更多...

头文件 #include <QMutex>
CMakefind_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core)
qmakeQT += core

注意:该类中所有函数都是线程安全

公有函数

QMutex()
~QMutex()
voidlock()
booltryLock(int timeout)
booltryLock()
(自6.6版起) booltryLock(QDeadlineTimer timer)
booltry_lock()
booltry_lock_for(std::chrono::duration<Rep, Period> duration)
booltry_lock_until(std::chrono::time_point<Clock, Duration> timePoint)
voidunlock()

详细描述

QMutex的作用是保护对象、数据结构或代码部分,使一次只有一个线程可以访问它(这类似于Java的synchronized关键字)。通常最好使用一个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()。非阻塞的替代方法是tryLock()。

QMutex针对非竞争情况进行了优化,以提高速度。在没有竞争的情况下,它不会分配内存。它的创建和销毁几乎没有开销,这意味着它可以作为其他类的一部分拥有很多互斥量。

相关链接 QRecursiveMutexQMutexLockerQReadWriteLockQSemaphore、和QWaitCondition

成员函数文档

[constexpr noexcept] QMutex::构造函数()

构建一个新的互斥锁。互斥锁以未锁定状态创建。

[noexcept] QMutex::~QMutex()

销毁互斥锁。

警告:销毁已锁定的互斥锁可能会导致未定义行为。

[noexcept] void QMutex::lock()

锁定互斥锁。如果另一个线程已锁定该互斥锁,则此调用将阻塞,直到该线程将其解锁。

从同一线程多次调用此函数将同一互斥锁会导致死锁

另请参阅:unlock

[noexcept] bool QMutex::tryLock(int timeout)

尝试锁定互斥锁。如果成功获得锁,此函数返回true;否则返回false。如果另一个线程已锁定互斥锁,此函数将等待最多timeout毫秒,直到互斥锁变为可用。

注意:将timeout传递为负数与调用lock()等效,即如果timeout为负数,此函数将无限期等待互斥锁可被锁定。

如果成功获得锁,必须在另一个线程可以成功锁定它之前,使用unlock()解锁互斥锁。

从同一线程多次调用此函数将同一互斥锁会导致死锁

另请参阅:lock() 和 unlock

[noexcept] bool QMutex::tryLock()

这是一个重载函数。

尝试锁定互斥锁。如果成功获得锁,此函数返回true;否则返回false

如果成功获得锁,必须在另一个线程可以成功锁定它之前,使用unlock()解锁互斥锁。

从同一线程多次调用此函数将同一互斥锁会导致死锁

另请参阅:lock() 和 unlock

[noexcept, since 6.6] bool QMutex::tryLock(QDeadlineTimer timer)

尝试锁定互斥锁。如果成功获得锁,此函数返回true;否则返回false。如果另一个线程已锁定互斥锁,此函数将等待直到timer过期,以便互斥锁变得可用。

如果成功获得锁,必须在另一个线程可以成功锁定它之前,使用unlock()解锁互斥锁。

从同一线程多次调用此函数将同一互斥锁会导致死锁

此功能自 Qt 6.6 中引入。

另请参阅:lock() 和 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()解锁互斥锁。

从同一线程多次调用此函数将同一互斥锁会导致死锁

另请参阅:lock() 和 unlock

模板 <typename Clock, typename Duration> bool QMutex::try_lock_until(std::chrono::time_point<Clock, Duration> 时间点)

尝试锁定互斥量。此函数如果成功获得锁定则返回 true,否则返回 false。如果另一个线程已锁定互斥量,此函数将等待直到 时间点,直到互斥量可用。

注意:传递一个已经过去的时间点相当于调用 try_lock()。这种行为与 tryLock() 不相同。

如果成功获得锁,必须在另一个线程可以成功锁定它之前,使用unlock()解锁互斥锁。

从同一线程多次调用此函数将同一互斥锁会导致死锁

另请参阅:lock() 和 unlock

[noexcept] void QMutex::unlock()

解锁互斥量。尝试在不同于锁定的线程中解锁互斥量会导致错误。尝试解锁未被锁定的互斥量会导致未定义的行为。

另请参阅 lock()。

© 2024 The Qt Company Ltd. 本文档中的文档贡献是各自所有者的版权。本文档是依照自由软件基金会发布并由其发布的 GNU自由文档许可证版本1.3 的条款提供的。Qt以及相关的商标是芬兰和/或世界各地的The Qt Company Ltd. 的商标。所有其他商标均为其各自所有者的财产。