我试图让一个线程用完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");
}
}
}
}
这个线程功能有更优雅的实现吗?
答案 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锁,原子整数等