2011-10-19 65 views
8

我在互斥析构函数中得到了字幕错误。由于错误可能是由于互斥锁在销毁期间处于锁定状态,所以我创建了一个从boost:mutex继承的新的互斥体类。它是确保互斥体在销毁期间解锁。但是,仍然会发生同样的错误。 任何点击将不胜感激!boost :: mutex ::〜mutex():声明`!pthread_mutex_destroy(&m)'失败

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(); 
} 

回答

7

boost::mutex请勿继承的boost::mutex类没有虚析构函数,所以它实际上并不意味着传承。

可能的根本原因:
你所得到的错误表明您正在一个从未锁定的互斥调用unlock。喜欢的东西:

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

通过尝试做lockunlock,似乎你失去的互斥体locked.This是很经常的问题,当你手动执行资源管理的轨道。 C++允许一个特定的机制,称为Resource Allocation is Initilization(RAII)为安全防范这些问题。

Suggestted解决方案:
您应该使用RAII,而不是明确地解锁互斥。您可以使用的boost ::互斥:: scoped_lock的实现RAII:

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

对不起。从核心来看,它表明它在互斥体的析构中失败了。是的。它只是一个测试来证明互斥锁处于解锁状态。 #0 0x0000003803030265来自/lib64/libc.so的raise()。6 (GDB)其中 #0 0x0000003803030265在从/lib64/libc.so.6 #1 0x0000003803031d10在中止()从/lib64/libc.so.6 #2 0x00000038030296e6在__assert_fail加注()(从)/ lib64/libc.so.6 #3 0x0000000000416314在boost :: mutex ::〜mutex()() –

2

POSIX指出,从pthread_mutex_destroy操作返回的唯一错误是EINVAL如果互斥体在某种程度上无效,或EBUSY如果有人使用它(明确地或通过条件变量)。

最可能的情况是第二个。

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

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

+0

所以如何在析构函数中打印出errno?关于m_block,另一个类将调用锁定和解锁函数,以便m_block被改变。我所做的只是确保互斥锁处于解锁状态。在析构函数中,互斥锁不需要在我的测试过程中调用解锁,这意味着互斥锁处于解锁状态 –

+0

@Michael,这是一个很好的观点,我刚刚意识到在返回之前你会声明,所以你不会得到打印errno的机会(pax疯狂地编辑他的答案)。至于你的第二点,尽管代码可能会_call_“锁定/解锁”,这不会改变'mbLock',因为你的成员函数永远不会改变它。 – paxdiablo

3

我有同样的错误(这是我如何发现这个问题)。我通过向相关主题添加join来解决问题。我的主要过程是在线程完成之前完成,并且mutex在它被解锁之前被拆除。