像 C# 一样在 Qt 中锁定对象

Lock objects in Qt like C#

本文关键字:Qt 锁定 对象 一样      更新时间:2023-10-16

在 C# 中,如果我有一个我可以做的列表

lock (this.mylist)
{
    ...
}

有了该代码,我相信在释放锁之前没有其他人可以使用该列表。这在多线程应用程序中很有用。如何在Qt上做同样的事情?我阅读了有关QMutex和QReadWriteLock的文档,但不知道如何在特定对象上使用它们。

要使用QMutex(或 C/C++ 中的任何标准同步方法),所有相互依赖的关键部分都必须了解互斥锁。确保这一点的最简单(但不是C++最佳实践,即使其成为类成员或其他东西)是创建一个全局变量互斥锁(例如我们将这样做)。

因此,请考虑以下几点

QMutex mutex;
void someMethod()
{
  mutex.lock();
  // Critical section
  mutex.unlock();
}

现在,lockunlock是原子方法,因此在任何给定时间只有一个线程能够进入关键部分。关键是两者都在尝试访问同一个互斥锁。

因此,从本质上讲,这与C#的工作方式相同,只是您需要自己管理互斥锁。因此,lock(...) { ... }块被替换为mutex.lock() ... mutex.unlock()。但是,这也意味着,无论何时要访问关键部分项(即在您的示例中,this->mylist),都应该使用互斥锁。

编辑Qt有非常好的文档。您可以在此处阅读有关QMutex的更多信息:http://doc.qt.io/qt-4.8/qmutex.html

执行此类操作的一般C++方法是使用 RAII,因此最终使用如下代码:

// Inside a function, a block that needs to be locked
{
  QMutexLocker lock(&mutex); // locks mutex
  // Do stuff
  // "QMutexLocker" destructor unlocks the mutex when it goes out of scope
}

我不知道这如何转换为 Qt,但是如果没有本机支持,您可能会编写一个帮助程序类。

编辑:感谢Cory,你可以看到Qt很好地支持了这个成语。

在 C++11 中,您可以执行以下操作:

#include <thread>
#include <mutex>
std::mutex mut;
void someMethod()
{
  std::lock_guard(mut);
  // Critical section
}

这是 RAII 惯用语 - 锁保护是一个对象,无论 someMethod 范围如何退出(正常返回或抛出),它都会释放锁。 请参阅安东尼·威廉姆斯的C++并发在行动。 他还有一个 C++11 线程实现。 C++11 实现与提升线程实现非常相似。