4

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

lock (this.mylist)
{
    ...
}

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

4

3 回答 3

2

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

所以考虑以下

QMutex mutex;

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

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

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

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

于 2012-04-25T16:19:22.300 回答
2

执行此类操作的一般 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 非常好地支持这个习语。

于 2012-04-25T16:24:28.533 回答
0

在 C++11 中,您可以这样做:

#include <thread>
#include <mutex>

std::mutex mut;

void someMethod()
{
  std::lock_guard(mut);
  // Critical section
}

这是 RAII 惯用语 - 锁守卫是一个无论 someMethod 范围如何退出(正常返回或抛出)都会释放锁的对象。请参阅 Anthony Williams 的 C++ concurrency In Action。他还有一个C++11 线程实现。C++11 的实现很像 boost 线程的实现。

于 2012-04-25T16:45:54.693 回答