【问题标题】:Boost mutex throw error on close for waiting threads等待线程关闭时提高互斥量抛出错误
【发布时间】:2012-12-27 18:48:31
【问题描述】:

有没有办法让 boost mutex 在任何等待线程上抛出异常?我有一个问题,其中一个对象被删除,但由于软件库的性质,线程可能仍在对象内的互斥锁处等待,并且当互斥锁关闭时抛出一个相当讨厌的异常。我想我可以使用多个互斥计数器,但这可能会导致性能下降。我想要发生的是互斥体在关闭时在等待的任何线程上抛出异常,以便展开堆栈。有没有一种独立于平台的干净方法?

【问题讨论】:

  • 其实没那么复杂。如果我关闭互斥锁,我希望所有等待的线程都获得标准 C++ 异常,而不是抛出断言或导致内存泄漏。
  • 如何“关闭”互斥锁?您的整个问题非常模糊,最终陷入这种情况似乎是糟糕的设计。等待线程在遇到异常时应该做什么?这些都没有任何意义,我很抱歉。
  • 您的对象生命周期似乎有问题,而不是互斥锁和线程

标签: c++ boost boost-thread


【解决方案1】:

这种在销毁时抛出的互斥锁的概念似乎无伤大雅,但到了实现它的时候,它揭示了您对互斥锁的思考方式的缺陷。

让我们看一些示例代码,以了解这种方法的缺陷。

注意:不要使用下面的代码,它只会带来无尽的折磨和调试同步问题。

class throwing_mutex
{
private:
    mutex m_;
    condition_variable cv_;
    bool destroyed_;
    bool locked_;

public:
    void lock()
    {
        std::unique_lock<std::mutex> lock(m_);
        cv_.wait(lock, [&]() {return !locked_ || destroyed_;}); // Wait until the mutex is unlocked or destroyed.
        if (destroyed_) throw runtime_error("The exception was terminated while waiting.");
        locked_ = true;
    }

    void unlock()
    {
        std::unique_lock<std::mutex> lock(m_);
        locked_ = false;
        lock.unlock();

        cv_.notify_one();
    }

    ~throwing_mutex()
    {
        std::unique_lock<std::mutex> lock(m_);
        destroyed_ = true;
        lock.unlock();

        cv_.notify_all(); // Let all waiters know we are dead.
    }
};

销毁后,所有等待throwing_mutex 的人都会抛出异常。但这开启了一个相当大的竞争条件。

我们已经处理了每个人都在等待互斥锁的情况——他们会安全地抛出。我们尚未处理的情况是有人正在打电话给lock() 但还没有到。当他们终于可以调用lock() 时,throwing_mutex 已经被销毁了。我们刚刚通过有缺陷的方法引入的错误称为use-after-free。如果我们幸运的话,错误会及早清晰地出现,但有时我们就没有那么幸运,我们会被折磨数小时或数天。我们的throwing_mutex 类无法解决这个问题,而且任何需要这样一个类的代码都没有经过深思熟虑的所有权语义。

那么,如果不是通过抛出的互斥锁,我们如何解决这个问题?我们修复了互斥体和被它锁定的对象的生命周期。

大概,这是互斥锁是一个类的成员。如果是这样的话,这意味着延迟销毁,直到依赖该对象的每个人都完成了它。这是使用shared_ptr 传达的。在不深入了解所有权语义的本质的情况下,这是可以回答的最好问题。希望我已经改变了你对问题的思考方式,足以让你偏离最初的计划,转向更可靠的工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-16
    • 2012-06-13
    • 1970-01-01
    • 2011-06-26
    • 1970-01-01
    • 2017-07-10
    相关资源
    最近更新 更多