項目簡介和code見《同步非同步和阻塞2-測試小項目》 1. 實現 1> 非同步線程IO處理 unsigned CAsyncIO::ThreadWork() { int nRet = IO(); //map is better than array at here, but it need STL un... ...
項目簡介和code見《同步非同步和阻塞2-測試小項目》
1. 實現
1> 非同步線程IO處理
unsigned CAsyncIO::ThreadWork() { int nRet = IO(); //map is better than array at here, but it need STL unsigned uTid = GetCurrentThreadId(); for (int i = 0; i < sizeof(m_uThreadArray) / sizeof(m_uThreadArray[0]); i++) { //Because handle is not same at different thread, so it need use tid to associate the thread and IO caller. if (uTid == m_uThreadArray[i]) { NotifyProgress(100, i); NotifyResult(nRet, i); } } return nRet; }
線程調用完IO後,直接通知UI結果。
2> OnStart()
bool CAsyncIO::OnStart() { OnStop(); for (int i = 0; i < sizeof(m_uThreadArray) / sizeof(m_uThreadArray[0]); i++) { HANDLE hThread = StartThread(); m_hThreadHandleArray[i] = hThread; m_uThreadArray[i] = ::GetThreadId(hThread); } return true; }
OnStart()只要把線程啟動處理IO即可返回,這樣就不會再阻塞UI主線程,”Start”按鈕在返回後會變為”Stop”。
3> Stop的實現
由於IO不再阻塞主線程,所以“Stop”按鈕變為可用,Stop的實現就變得有意義。
bool CAsyncIO::OnStop() { for (int i = 0; i < sizeof(m_hThreadHandleArray) / sizeof(m_hThreadHandleArray[0]); i++) { HANDLE hThread = m_hThreadHandleArray[i]; if (hThread) { TerminateThreadUntilExit(hThread); ::CloseHandle(hThread); m_hThreadHandleArray[i] = NULL; } } return true; }
這裡Stop()的實現僅僅是簡單的Terminate掉線程,由於直接終止線程,無法知道線程所處的狀態,會出現什麼情況無法預知,有時會出現莫名奇妙的問題,微軟也是不推薦的,需謹慎使用。
2. 測試
點擊”Start”按鈕後,雖然IO沒有處理完畢,但是按鈕立即變為可用的”Stop”,同時UI視窗也是可以隨意移動操作的。
非同步非阻塞模式不阻塞UI主線程,用戶體驗上是最好的。同時在併發處理上也相對同步非阻塞模式簡單,當然由於需要在IO處理完畢後通過callback通知UI主線程,這必然會涉及到線程同步的問題,線程同步是個非常頭疼的問題,在非同步模式帶來的好處不是遠遠大於同步模式的情況下,其帶來的問題會遠遠大於同步模式。