在构造函数中睡眠线程和线程初始化

时间:2014-08-13 14:02:06

标签: c++ multithreading c++03

我试图让一个线程用完ctor,线程应该睡眠,唤醒,然后执行缓冲区转储,然后再次睡眠等等,这就是ctor的代码:

 Logger::Logger()
 {
   BufferInUse = &CyclicBuffer1;                        //buffer 1 will be used at    beggining
   MaxBufferSize = 5;                                   //initial state
   NumOfCycles = 0;
   CurrentMaxStringLength = 0;

   position = BufferInUse->end();
   OutPutMethod = odBuffer;                         //by default
   Thresh = 1;                                      //by default

   hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
   EventTime.QuadPart = -20000000;                          //1 second by default
   Mutex =  CreateMutex(NULL,FALSE,NULL);   
   if (Mutex == NULL) 
   { 
       OutputDebugStringA("CreateMutex error! the Logger will close \n");
       return ;
   }
   _beginthread( Logger::WorkerThread , 0,(void*)this );    //run the thread
}

当我调试它时,甚至需要花费大量时间来创建线程并完成ctor函数,但在那段时间我的对象成员函数被多次调用(我在调试时看到它)。 1.我希望在我的成员函数被调用之前创建线程,实现它的最佳方法是什么?

现在我的线程实现是:

               void Logger::WorkerThread ( void *lpParam )
              {
                   Logger *log = static_cast <Logger*> (lpParam);
                   if (NULL == log->hTimer)
                   {
                      log->LogStringToOutput("CreateWaitableTimer() failed , Logger will close \n");
                       return;
                    }

               for(;;)
               {
                 //set timer for time specified by the EventTime variable inside the Logger
                 if (!SetWaitableTimer(log->hTimer, & (log->EventTime), 0, NULL, NULL, 0))
                 {
                     log->LogStringToOutput("SetWaitableTimer() failed , Logger will close\n" );
                    _endthread();
                 }

               //wait for timer
              if (WaitForSingleObject(log->hTimer, INFINITE) != WAIT_OBJECT_0)
              {
                   log->LogStringToOutput("WaitForSingleObject() failed! Logger will close\n");
                  _endthread();
                  return;
              }

              if(log->getOutputMethod() == odBuffer && log->BufferInUse->size() >= log->Thresh && !log->BufferInUse->empty())
              {
                  TTFW_LogRet ret;
                 ret = log->FullBufferDump();
                 if (ret != SUCCESS)
                 {
                       log->LogStringToOutput("Error occured in dumping cyclic buffer , the buffer will be cleared\n");
                 }
             }
           }

        }

这个线程功能有更优雅的实现吗?

1 个答案:

答案 0 :(得分:1)

您需要一些机制来同步WorkerThread启动和成员函数访问。

例如,

使用条件变量(documents in msdn):

将3个成员添加到Logger:

class Logger{
...

private:        
    CRITICAL_SECTION CritSection;
    CONDITION_VARIABLE ConditionVar;
    bool WorkerThreadStarted;

...
};

 Logger::Logger():WorkerThreadStarted(false)
 {
     EnterCriticalSection(&CritSection); //added

     BufferInUse = &CyclicBuffer1;    //buffer 1 will be used at    beggining

     ...
  }

 void Logger::WorkerThread ( void *lpParam )
 {

     WorkerThreadStarted=true; //added
     LeaveCriticalSection(&CritSection);

     Logger *log = static_cast <Logger*> (lpParam);
     if (NULL == log->hTimer)
     {
        log->LogStringToOutput("CreateWaitableTimer() failed , Logger will close \n");
         return;
     }


     ...
}

添加这样的功能:

  void Logger::EnsureInitiallized(){

      EnterCriticalSection(&CritSection);

      // Wait until the predicate is TRUE

      while( !WorkerThreadStarted )
      {
         SleepConditionVariableCS(&ConditionVar, &CritSection, INFINITE);
      }

      LeaveCriticalSection(&CritSection);
  }

并在每个成员函数的条目中,调用EnsureInitiallized();

  void Logger::yourFunction(){
    EnsureInitiallized();

    ...
  }

这是一个例子,你也可以使用read_write锁,原子整数等