0
这是我第一次使用事件同步线程。我的代码工作正常。但正如我经历的那样,它看起来不错,但有明显的缺陷,当我在更大的项目中使用这个概念时,这真的很难找到。使用事件来同步线程
所以我只是想问,这种使用事件来同步线程的方式对您来说看起来不错吗?
这个想法是我们有GetSymbol函数,它只能从主线程调用。服务器线程需要向主线程询问这个函数的结果。
#include <windows.h>
#include <process.h>
#include <stdio.h>
HANDLE symbol_need, symbol_ready, end;
int symbol_container;
int GetSymbol()
{
// Only main thread can use this function.
static int i = 0;
return ++i;
}
void Server(void* p)
{
printf("Ask for first symbol.\n");
SetEvent(symbol_need);
DWORD wait_result;
wait_result = WaitForSingleObject(symbol_ready, INFINITE);
if(WAIT_OBJECT_0 == wait_result)
{
ResetEvent(symbol_ready);
printf("First symbol: %i\n", symbol_container);
} else {
printf("Something went wrong.\n");
}
printf("Ask for second symbol.\n");
SetEvent(symbol_need);
wait_result = WaitForSingleObject(symbol_ready, INFINITE);
if(WAIT_OBJECT_0 == wait_result)
{
ResetEvent(symbol_ready);
printf("Second symbol: %i\n", symbol_container);
} else {
printf("Something went wrong.\n");
}
printf("OK, finish it.");
SetEvent(end);
}
int main(int argc, char* argv[])
{
symbol_need = CreateEvent(NULL, FALSE, FALSE, NULL);
symbol_ready = CreateEvent(NULL, FALSE, FALSE, NULL);
end = CreateEvent(NULL, FALSE, FALSE, NULL);
_beginthread(Server, 0, NULL);
DWORD wait_result;
while(1)
{
wait_result = WaitForSingleObject(symbol_need, 100);
if(WAIT_OBJECT_0 == wait_result)
{
ResetEvent(symbol_need);
symbol_container = GetSymbol();
SetEvent(symbol_ready);
}
wait_result = WaitForSingleObject(end, 100);
if(WAIT_OBJECT_0 == wait_result)
{
break;
}
}
return 0;
}
该代码有一个难闻的气味。对ResetEvent的调用是多余的(因为您使用自动重置事件),最糟糕的情况是可能导致事件丢失,导致死锁。只需删除它们。 – arx 2012-03-05 23:20:48
@arx实际上,由于主线程在“服务器”线程发出其事件之前无法为下一次迭代执行“SetEvent”,因此“服务器”线程无法意外重置自己的事件。但我同意他应该切换到手动事件或删除重置。 – Tudor 2012-03-05 23:30:48