c++ - Boost mutex 在等待线程关闭时抛出错误

标签 c++ boost boost-thread

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

最佳答案

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

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

注意:不要使用下面的代码,它只会导致无休止的折磨和痛苦的调试同步问题。

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 类无法解决该问题,任何需要此类的代码都没有经过深思熟虑的所有权语义。

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

据推测,这是mutex是一个类的成员。如果是这种情况,则意味着延迟销毁,直到依赖该对象的每个人都完成了它。这是通过使用 shared_ptr 传达的。 .在不深入了解所有权语义的细节的情况下,这是最好的答案。希望我已经改变了你思考问题的方式,足以让你偏离最初的计划,转向更可靠的计划。

关于c++ - Boost mutex 在等待线程关闭时抛出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14307785/

相关文章:

c++ - 使用 vector::push_back 移动

c++ - 在编译时静态检查 map ?

c++ - 如何在 C++ 中的低优先级线程中运行方法?

c++ - 我是否过度设计了每线程信号阻塞?

c++ - 为什么这段代码会导致死锁?

c++ - 为什么 mingw 4.4 说 <random> 需要 c++0x?

c++ - Boost.asio 端点是否可以用于识别 UDP 连接的客户端?

c++ - 只读 std::map?

c++ - boost.thread - 一个简单示例中的访问冲突

boost-thread - 雇用,libev和boost:threads