多线程对象中的堆损坏

heap corruption in multi-threaded object

本文关键字:损坏 对象 多线程      更新时间:2023-10-16

我试图建立一个单例类,它将保持一个循环缓冲区,每次一些函数想要转储发送一些东西到调试客户端(例如DBGview或类似)该函数将其信息存储在循环缓冲区内。该对象还将运行一个线程,该线程将休眠一段时间,然后唤醒并将缓冲区内容转储到调试客户端。

这是每个人在需要发送一些东西进行调试时调用的函数:

     TTFW_LogRet PrintToLogger (std::string Str)
     {
         Logger *Log;
         if(Instance_Mutex == NULL)
         {
              Instance_Mutex = CreateMutex(NULL,FALSE,NULL);
              if (Instance_Mutex == NULL) 
              {
                   OutputDebugStringA("CreateMutex error! the Logger will close n");
                   return GENERAL_ERROR;
              }
          }
          Log = Logger::getLogInstance();
          Log->LogStringToOutput(Str);
          return SUCCESS;
       }

由于某种原因,我总是在返回SUCCESS语句后得到堆损坏错误

这是Getinstance()函数:

Logger* Logger::getLogInstance()
{
    if(_instance == NULL)
    {
       MutexLock(Instance_Mutex);
       if(_instance == NULL)
       {
           _instance = new Logger();
       }
       MutexUnlock(Instance_Mutex);
   }
   return _instance;
  }

,线程函数为

    DWORD WINAPI Logger::WorkerThread (LPVOID lpParam )
    {
         Logger *log = static_cast <Logger*> (lpParam);
         for(;;)
         {
              Sleep(2000);
              if(log->getOutputMethod() == odBuffer && log->CyclicBuffer1.size() >= log->Thresh && !log->CyclicBuffer1.empty())
         {
                  TTFW_LogRet ret;
                  ret = log->FullBufferDump();
                  if (ret != SUCCESS)
                  {
                       log->LogStringToOutput("Error occured in dumping cyclic buffer , the buffer will be clearedn");
                  }
            }
          }
         }

有人知道为什么堆损坏会发生在这段代码中吗?请注意,要调试的函数会被调用很多次,并且它不会与转储缓冲区的线程同步。

您使用了双重检查锁定,这可能会导致您所看到的那种微妙的问题。特别地,c++允许

_instance = new Logger();

可能导致_instanceLogger构造函数完成之前得到非null值。然后,如果另一个线程调用getLogInstance,条件if(_instance == NULL)将不满足,线程将使用未完全初始化的对象。考虑使用直接锁定而不进行双重检查,或者使用其他技术(可能依赖于实现)。在c++ 11中,您可以安全地使用静态变量来实现这些目的。

我的通灵调试技能告诉我LogStringToOutput不是线程安全的,并且在从多个线程调用时导致堆损坏。