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