我的代码如下,Ax内部的ASSERT没报错, 但程序退出时Lock报错,此时m_nCount等于0
class Ax
{
public:
Ax(CSingleLock* psl)
: m_psl(psl)
{
BOOL b = m_psl->Lock(); // ASSERT(b);
InterlockedIncrement(&m_nCount);
}
~Ax()
{
BOOL b = m_psl->Unlock();
ASSERT(b);
InterlockedDecrement(&m_nCount);
}
protected:
Ax();
CSingleLock* m_psl;
static long m_nCount;
};long Ax::m_nCount = 0;下面这个函数供多个线程调用
void CDbgLogWnd::SendDbgLog(PRIVATE_DBG_LEVEL nLevel,  TCHAR *buffer)
{ if (!m_pwndDbgLog || !m_pwndDbgLog->GetSafeHwnd()  || !::IsWindow(m_pwndDbgLog->GetSafeHwnd()))
return;
ASSERT(nLevel < MAX_DBG_LEVEL);
Ax _ax(&m_pwndDbgLog->m_dbgLogLock);//CSingleLock(&CMutex ...)
...
}程序退出时会报下面红字的ASSERT错误,请问是什么原因?
BOOL CSingleLock::Lock(DWORD dwTimeOut /* = INFINITE */)
{
ASSERT(m_pObject != NULL || m_hObject != NULL);
ASSERT(!m_bAcquired); m_bAcquired = m_pObject->Lock(dwTimeOut);
return m_bAcquired;
}

解决方案 »

  1.   

    说明你那个CSingleLock对象自己有问题了,你应该看系统到底在ASSERT什么
      

  2.   

    从代码看,你这个类不允许你lock两次,这似乎有点非常不合理,这个类是系统提供的?
      

  3.   

    你在什么地方已经锁定了资源,在未解锁之间,不能重复锁定。
    将你调用Lock的代码贴出来
      

  4.   

    Ax 只在那个void CDbgLogWnd::SendDbgLog(PRIVATE_DBG_LEVEL nLevel,  TCHAR *buffer) 函数里用了,使用它是为了利用它的构造和析构函数原理,在SendDbgLog中自动调用lock和unlock
      

  5.   

    报错时, CDbgLogWnd对象还是好的
      

  6.   

    调用lock的地方就是Ax的构造函数
      

  7.   

    你怎么不去尝试理解人家的回复,说这些无关的干吗?不是告诉你了么?这个错误是因为“lock”两次导致的。这对于多线程程序是非常不合理的,这个assert不应该合理。你的这个类是系统提供的么?
      

  8.   

    仔细看了MSDN说明,这个SingleLock类不是你这么用的,他不应该被你保存和传递,他应该只在一个函数的作用域内部使用,常见方法是void MyFunc()
    {
         CSingleLock lokc(m_mutex);
         // your code here
    }
    你一旦保存和传递这个对象,必然造成问题。而从你代码看,他显然被你当作成员变量保存了
      

  9.   

    这个类是我自己写的.是否是lock了以后,没有Unlock,然后又lock了?如果是这样,那么此时Ax::Ax里面lock时,m_nCount应该大于0吧?
      

  10.   

    这个类是我自己写的.是否是lock了以后,没有Unlock,然后又lock了?如果是这样,那么此时Ax::Ax里面lock时,m_nCount应该大于0吧?
      

  11.   

    如果多个线程同时使用他,有可能出现这种情况
    1. 线程1调用Lock,修改了m_bAcquired,但是还没有修改m_nCount就被线程2抢了CPU
    2。线程2再调用lock就出现这种问题总之这是你用法错误,还是好好理解一下single lock干吗再说