【问题标题】:Does QMutexLocker return the error code (if any)?QMutexLocker 是否返回错误代码(如果有)?
【发布时间】:2012-08-13 11:56:36
【问题描述】:

http://doc.qt.io/archives/qt-4.7/qmutexlocker.html

这个类在其构造函数中锁定了互斥体,所以如果在互斥体创建时发生错误,我们是否能够知道是什么错误(构造函数不返回任何内容)?

这是某种劣势吗?

我在这里漏掉了一点吗?

【问题讨论】:

  • 如果您担心bad_alloc,请先创建互斥体,在创建储物柜之前对其进行测试。你特别担心会发生什么?
  • @cbamber85 我认为 QMutexLocker 类可以“安全地”使用——不用担心“任何事情”!如果我们不将互斥锁锁定在构造函数中,而是将其锁定在返回错误代码的单独类函数中,这会是一个糟糕的设计吗?

标签: c++ qt pthreads mutex


【解决方案1】:

QMutexLocker 接受一个指向(并处理)QMutex 对象的指针,而不是pthread_mutex_t 对象(即使a QMutex 可能在pthread_mutex_t 之上实现)。

锁定/解锁 QMutex 对象不会返回任何类型的错误代码(QMutex::lock()QMutex::unlock() 返回 void)。

在较低的“pthread 级别”可能发生的任何错误都将由QMutex 对象在内部处理,导致 C++ 异常,或者导致代码中的缺陷(例如死锁)(例如如果您尝试递归获取非递归的QMutex)。

【讨论】:

  • 所以使用起来并不安全,这意味着!我被它作为 Qt 的一部分迷住了。
  • Qt 做出设计选择,不提供某些类型的错误处理,以提供良好的 API - 最值得注意的是它不使用异常。但是,刚刚查看了相关的 Qt 源代码(如果您有顾虑,我建议您也这样做):EBUSY 不相关,因为它仅适用于 tryLock()。 EAGAIN 也不适用,因为 Qt 使用它自己的递归锁计数器。当然可能会发生其他错误,但它们极不可能发生。如果您需要这种级别的错误检查,您将需要找到另一种解决方案,但对于绝大多数用途来说它是“安全的”。
【解决方案2】:

您可能会混淆互斥锁和锁。 mutex 是共享同步对象。 是本地对象,对每个执行上下文都是本地的,通过锁定公共互斥锁来实现同步。因此,必须存在互斥锁才能使锁有意义:

Foo sharedData;           // \ global/
QMutex sharedDataMX;      // / shared

void run_me_many_times()
{
    QMutexLocker lk(&sharedDataMX);

    // access "sharedData"
}

【讨论】:

  • 谢谢,但pthread_mutex_lock 返回几种错误,如 EBUSY 等。因此,互斥变量可能肯定存在,但仍然可能发生错误,如 - EAGAIN
  • QMutexLocker 这样的简单 SBRM 储物柜类不适合复杂的锁定语义。它所做的一切都提供了一个简单的阻塞锁定/解锁。如果您需要更精致的东西,您需要直接连接互斥锁(例如某种形式的try_lock)。一个 C++ 风格的简单 lock() 除了通过异常之外不会失败,所以如果你的代码流过 lock() 调用,你肯定会得到锁。
猜你喜欢
  • 2016-09-30
  • 1970-01-01
  • 2013-01-30
  • 2023-03-25
  • 1970-01-01
  • 2017-03-24
  • 1970-01-01
  • 2016-03-15
  • 2012-06-28
相关资源
最近更新 更多