【问题标题】:Using QMutex::tryLock and QMutexLocker使用 QMutex::tryLock 和 QMutexLocker
【发布时间】:2013-12-03 11:23:27
【问题描述】:

我有一个后台功能,目前有如下内容:

void SomeClass::someFunction()
{
    if (!_mutex.tryLock())
    {
        // i want to know the mutex is locked, and then exit the function
        return;
    }
    else
    {
        _mutex.unlock();
    }

    QMutexLocker locker(_mutext);

    // do some stuff that **could** throw an exception
}

我的困境与_mutex.unlock()QMutextLocker 声明有关。

如果_mutex 被锁定,那么我想知道它。如果不是,那么我想锁定它。问题是我想使用QMutexLocker 来锁定_mutex 的大部分功能。该函数可能会引发异常,因此手动解锁_mutex 可能很困难且容易出错。

上述解决方案有效,但我担心的是,在 _mutex.unlock()QMutexLocker 减速之间的某个时间可能会出现其他东西并锁定互斥锁。

有没有人有更好的方法来做这件事的建议?

谢谢。

【问题讨论】:

  • 你想在等待锁的时候做一些工作吗?
  • 我更新了代码以更好地反映我想要做的事情。如果互斥锁被锁定,我想做一些事情然后退出函数。
  • 这里有同样的问题。也想有一个支持tryLock的QMutexLocker。

标签: c++ qt concurrency mutex


【解决方案1】:

QMutexLocker 显然不能完全满足您的需求,但您可以轻松编写自己的 RAII 包装器:

class MutexTryLocker {
  QMutex &m_;
  bool locked_;
public:
  MutexTryLocker(QMutex &m) : m_(m), locked_(m.tryLock()) {}
  ~MutexTryLocker() { if (locked_) m_.unlock(); }
  bool isLocked() const { return locked_; }
}

并像这样使用它:

void SomeClass::someFunction() {
    MutexTryLocker locker(_mutex);

    if (!locker.isLocked()) {
        // we didn't get the lock, so return
        return;
    }

    // do some stuff that **could** throw an exception
}

请注意,这个储物柜只是示例代码:生产版本可能应该是明确不可复制的。


历史记录:JBL 的评论提到了一段针对问题中不再存在的句子的段落。我将其解释为:

...其他东西可能会出现并锁定互斥锁

如果可能,它发生。如果不太可能,只有在您部署/扩大/出售给客户之后才会发生。

【讨论】:

【解决方案2】:

我遇到了类似的情况,最终使用了等效的标准组件而不是 Qt 组件,因为它们的 lock_guard 能够处理已经锁定的互斥体。如果这是某人的选择,您可以这样做:

#include <mutex>

std::mutex _mutex;

void SomeClass::someFunction()
{
    if (!_mutex.try_lock())
    {
        // i want to know the mutex is locked, and then exit the function
        return;
    }

    // The lock_guard overtakes the already locked mutex
    const std::lock_guard<std::mutex> locker(_mutex, std::adopt_lock);

    // do some stuff that **could** throw an exception
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-05
    • 2012-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多