【问题标题】:explicitly calling ~boost::lock_guard<> causes mutex deadlock显式调用 ~boost::lock_guard<> 导致互斥锁死锁
【发布时间】:2012-09-07 15:00:42
【问题描述】:

如果这是一个错误,我只是不这样做没有问题,但如果这是预期的行为,我想知道为什么。

我会这样做:

{
   boost::lock_guard<boost::mutex> lg(tagsToSocketsMtx);
// mutex protected work 
   lg.~lock_guard(); // this causes deadlocks later(combined with ...
  //...other uses of the same mtx, ofc I use different lock guard in other functions)

// rest of the function
}

【问题讨论】:

    标签: boost mutex


    【解决方案1】:

    一旦lg 的构造完成,C++ 保证将在范围退出时调用其析构函数无论您是否也在进行显式析构函数调用

    通过两次销毁lg,您正在调用未定义的行为,在这种情况下,错误表现为死锁。

    【讨论】:

    • 哎哟......我认为这只是将破坏向前移动,但现在当我想到它时,通常不可能确定是否会调用显式析构函数(如果它在 if 语句中)。 ..所以是的,我很愚蠢...顺便说一句,为什么C ++允许显式调用dtors?这似乎是一个可怕的想法。是否可以赋予 delete 特殊权限,以便它可以调用 dtor,但用户不能?
    • @NoSenseEtAl:显式析构函数调用(与放置 new 配对时)的典型用法是将对象生命周期与内存分配分开。
    • tnx,如果有人想知道我为什么会犯这样一个愚蠢的错误...我记得使用了一个类似的类,我认为 C++11 有解锁方法,因为性能原因所以当我没有找到它时我明确地调用了析构函数。 ://
    • “通过两次销毁 lg,你正在调用未定义的行为”,你确定吗?这肯定不是使用锁守卫的预期方式,但我认为从技术上讲,多次调用析构函数(而不是删除)不是 UB。
    • @enobayram:是的,但更有用的结果是析构函数不必以安全多次调用的方式编写。
    猜你喜欢
    • 2011-03-03
    • 2014-05-24
    • 1970-01-01
    • 2015-10-26
    • 2012-10-18
    • 1970-01-01
    • 1970-01-01
    • 2022-06-13
    • 2012-03-25
    相关资源
    最近更新 更多