【问题标题】:boost::mutex::~mutex(): Assertion `!pthread_mutex_destroy(&m)' failedboost::mutex::~mutex(): 断言 `!pthread_mutex_destroy(&m)' 失败
【发布时间】:2011-12-10 15:45:29
【问题描述】:

我在互斥体析构函数中得到了标题错误。由于该错误可能是由于互斥体在销毁期间处于锁定状态,因此我创建了一个新的互斥体类,该类继承自 boost:mutex。这是为了确保在销毁过程中互斥锁是解锁的。但是,仍然会发生相同的错误。 任何点击将不胜感激!

class CMutes : public boost::mutex
{
public:
    CMutes()
    {

    };

    virtual ~CMutes()
    {
        if (m_bLock)
            boost::mutex::unlock();
    };

    void lock()
    {
        if(!m_bLock)
            boost::mutex::lock();
        else
            cout << "Mutex is in lock state\n";
    };

    void unlock()
    {
        if (m_bLock)
            boost::mutex::unlock();
        else
            cout << "Mutex is in unlock state\n";
    }

    boost::mutex& getMutex()
    {
        return *this;
    }

private:

    bool m_bLock;
};

编辑: 是的,你是对的。我应该使用 RAII。但是,我有一种情况。我需要在另一个线程完成处理之前锁定资源。如下所示。

Thread A:
void getDate()
{
 m_oLock.lock();
 // access resource
}

void unlock()
{
 m_oLock.unlock();
}
Thread B:
void Process()
{
 threadA.getData();
 threadA.unlock();
}

【问题讨论】:

    标签: c++ boost mutex


    【解决方案1】:

    不要继承自boost::mutex,boost::mutex 类没有虚拟析构函数,因此它实际上并不意味着继承。

    可能的根本原因:
    您收到的错误表明您在从未锁定的互斥锁上调用 unlock。类似的东西:

    boost::mutex m;   
    m.unlock(); 
    

    通过尝试执行lock 和unlock,您似乎忘记了互斥锁是否已锁定。这是您手动执行资源管理时经常遇到的问题。 C++ 允许使用名为 Resource Allocation is Initilization(RAII) 的特定机制来安全防范此类问题。

    建议的解决方案:
    您应该使用 RAII,而不是显式解锁互斥锁。您可以使用 boost::mutex::scoped_lock 来实现 RAII:

    struct YourStruct
    {
        void doSomething()
        {
            boost::mutex::scoped_lock l(m_mutex);
            //do something Interesting
        }
        private: 
            boost::mutex m_mutex;
    };
    

    【讨论】:

    • 对不起。从核心,它表明它在互斥体的析构函数中失败。是的。这只是证明互斥锁处于解锁状态的测试。 #0 0x0000003803030265 in raise () from /lib64/libc.so.6 (gdb) where #0 0x0000003803030265 in raise () from /lib64/libc.so.6 #1 0x0000003803031d10 in raise () from /lib64/libc.so .6 #2 0x00000038030296e6 in __assert_fail () from /lib64/libc.so.6 #3 0x0000000000416314 in boost::mutex::~mutex() ()
    【解决方案2】:

    我遇到了同样的错误(这就是我发现这个问题的方式)。我通过在相关线程中添加join 解决了问题。我的主要进程在线程完成之前完成,mutex 在解锁之前被拆除。

    【讨论】:

      【解决方案3】:

      POSIX 指出,如果互斥锁因某种原因无效,则从 pthread_mutex_destroy 操作返回的唯一错误是 EINVAL,或者如果有人正在使用它(显式地或通过条件变量),则返回的错误是 EBUSY。

      最有可能的情况是第二种情况。

      但是,我在您的任何代码中都没有看到对 m_bLock 成员变量的任何更改。您确定不想在 lock 和 unlock 调用中更改此变量吗?

      如果它在使用中,你只需要等到使用它的人愿意释放它。任何其他选择都不太可能对你有好处:-)

      【讨论】:

      • 那么如何在析构函数中打印出 errno 呢?对于 m_bLock,其他类会调用 lock 和 unlock 函数来改变 m_bLock。我所做的只是确保互斥锁处于解锁状态。而在析构函数中,互斥体在我的测试过程中不需要调用解锁,这意味着互斥体处于解锁状态
      • @Michael,这是一个很好的观点,我刚刚意识到你会在返回之前断言,所以你不会有机会打印出 errno(pax 疯狂地编辑他的答案)。至于您的第二点,尽管代码可能调用 lock/unlock,但这不会改变mbLock,因为您的成员函数永远不会改变它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-03
      • 1970-01-01
      • 2011-12-15
      • 1970-01-01
      • 2011-01-17
      • 1970-01-01
      • 2011-02-22
      相关资源
      最近更新 更多