multi-thread 同步問題  

2009年4月3日 星期五 , Posted by 曾easy in ,

環境:wince 5.0, vc2005
問題:
我有一個process(主程式) 開了一個thread(用來接收radius response的回應), 主程式呼叫ACE_Thread_Manager::instance()->wait();後, 主程式永遠無法結束!


解決:使用 WaitForSingleObject();

在主程式宣告 global 變數 HANDLE g_hEvent;

g_hEvent = CreateEvent(NULL, TRUE, TRUE, L"VMAX_THREAD_EVT");
ResetEvent(g_hEvent); // 先用ResetEvent()將其設成未觸發狀態
... spawn thread ...;
switch (WaitForSingleObject( g_hEvent, 30000)) //等待thread
{
case WAIT_OBJECT_0:
// The thread has terminated - do something

break;
case WAIT_TIMEOUT:
// The timeout has elapsed but the thread is still running
// do something appropriate for a timeout
break;
}


在處理回應的程式碼 (thread會執行的地方)

ResetEvent(g_hEvent);
... 處理 ...;
SetEvent(g_hEvent); //用SetEvent()觸發event , 主程式的process便可以繼續執行


######################################################
同步就是說 當兩個執行緒同時在跑的時候 A執行緒需要等B執行緒跑完之後才進行下個動作
或者是有一個資源(如網路,圖片,DC....)同時只能有一個執行緒在使用 其他必須要等他用完才能繼續動作

CreateEvent(NULL,TRUE,TRUE,"MY_THREAD_EVT");
第一個是安全設定 這個通常不需要設定他

第二個參數為是否手動設定unsigaled狀態
TRUE代表我們必須要使用ResetEvent()來將他變回未觸發狀態 否則我們無法再觸發他
FALSE的話 代表event觸發完之後 他會自動變回未觸發狀態 我們可以馬上再觸發

第三個參數是初始狀態 FALSE代表初始狀態為未觸發狀態 此時我們可以觸發他

第四個參數是我們所給的名字 以後可以透過這個名字來開啟這個handle 開啟法如下

HANDLE g_hOutEvent =
::OpenEvent(EVENT_ALL_ACCESS,FALSE,"MY_THREAD_EVT");



OpenEvent()是讓我們在其他行程(Process)中也能共享同一個event
接下來便是同步了 同步可以使用WaitForSingleObject()來達成
範例如下

// process A
void Run()
{
::ResetEvent(g_hEvent);

// 在這裡執行process A的工作
::SetEvent(g_hEvent);
}



// process B
void
WaitTeminate()
{
// 等待Process A完成
::WaitForSingleObject(g_hOutEvent,INFINITE);
}



以上兩個行程A B 共用同一個event 且行程B已使用OpenEvent()開啟行程A的event
當A開始執行前 先用ResetEvent()將其設成未觸發狀態
之後行程B只要執行到WaitForSingleObject()便會開始等待
行程A執行完成之後 會用SetEvent()觸發event
接下來在行程B中的WaitForSingleObject()便可以離開等待狀態 繼續執行了

最後 event不用的時候 要將他關閉
::CloseHandle(g_hOutEvent);

Reference from http://blog.yam.com/swwuyam/article/11418020

This entry was posted on 2009年4月3日 星期五 at 上午11:30 and is filed under , . You can follow any responses to this entry through the comments feed .

0 意見

張貼留言