WIN32多線程程式設計學習筆記(第四章 下 第五章)

來源:互聯網
上載者:User
終於又看<<WIN32多線程程式設計>>了;開卷有益,今天看了第四章後半部分,感覺頗有收穫;以前對EVENT這個核心對象,用起來總是心中沒底,看了EVENT的介紹也是似懂非懂的。哈!今天看了以後,真有神助,我覺得應該是搞懂了(自以為事J)。仔細想想,應該是記筆記的功勞,用腦筋寫過的東西還真是不容易忘記咧!!!不但印象深刻,而且助我理解了EVENT。 好了,閑話少說,進入正題吧!從第三章以來,每一章都必不可少的用到了一個重要的函數,知道是什麼嗎? ――――WaitFor…. () 系列//快速複習判斷一個線程是否結束:WaitForSingleObject ( HANDLE hthred …. );判斷是否能夠進入關鍵地區:WaitForSingleObject ( hMutex….) ;  Wait….()會在核心對象被激發時返回,各種核心對象對激發的定義不甚相同,對於hthred而言,線程結束,意味著核心對象被激發;對於hMutex而言, hMutex不再被其它任何線程使用,意味著核心對象被激發。 反正對於各種核心對象而言,一定是有某種情境的出現使得核心對象被激發,除了EVENT 這個核心對象。 對於EVENT這個核心對象而言,它的激髮狀態完全由程式來控制,也就是說,由自己來控制EVENT的激發或未激髮狀態( 通過SetEvent() , ResetEvent() )。當 線程1因調用Wait…(hEvent)而被阻塞後,一定是某個線程調用了SetEvent( hEvent )使hEvent被設為激髮狀態,從而使線程1被解除阻塞繼續向下運行,具體的運用參見下表: 
函數 EVENT對象[Manual方式產生] EVENT對象[Auto方式產生]
Wait…() 當EVENT對象變為激髮狀態(使得因調用Wait…()而等待的線程被喚醒)之後,不會被重設為非激髮狀態(必須調用ResetEvent()) 當EVENT對象變為激髮狀態(使得因調用Wait…()而等待的線程被喚醒)之後,自動重設為非激髮狀態
SetEvent() 把EVENT對象設為激髮狀態 把EVENT對象設為激髮狀態
ResetEvent() 把EVENT對象設為非激髮狀態 把EVENT對象設為非激髮狀態
PulseEvent() 把EVENT對象設為激髮狀態,喚醒“所有”等待中的線程,然後把EVENT對象設為非激髮狀態 把EVENT對象設為激髮狀態,喚醒“一個”等待中的線程,然後把EVENT對象設為非激髮狀態
[使用CreateEvent () API函數構造EVENT核心對象,CreateEvent ()的第二個參數決定了產生的EVENT對象是Manual(手工)方式還是Auto(自動)方式;第三個參數決定了決定了產生的EVENT對象初始狀態是激發還是未激發] EVENT核心對象的不同的狀態(初始狀態是激發還是未激發)及不同的類型(Manual[手工]方式還是Auto[自動]),與之對應的處理方式也就不一樣,情況太多了真是不好一一舉例,以後補上J(在下面第五章中,我舉了一個例子) 值得注意:使用PulseEvent()方法激發EVENT的請求可能會被遺失,由此可能產生的一系列問題在P124有很精彩的描述,值得一看(由此描述引出了semaphore同步機制)。 至此,第四章差不多可以結束了(除了semaphore,Interlocked ,自己看一下吧!) 下面進入第五章:   如何強制結束一個線程?查查有關線程的API函數,立刻便找到一個結束線程的函數―――――TerminateThread ( ) ; 用它嗎?噢! 不要使用它。被TerminateThread ( )強制結束的線程可能會有造成以下後果:1、 沒有機會在自己結束前釋放自己所使用的資源2、 可能引起記憶體流失3、 如果這個線程被結束時處於一個critical section之中,那麼該critical section將因此永遠處於鎖定狀態。  那麼如何強制結束一個線程?書上給出了一個例子,以後強制結束一個線程就靠它了。程式片段: // 線程退出事件 HANDLE hExitEvent = null ; // 一個需要長時間啟動並執行線程 DWORD WINAPI ThreadFun ( LPVOID p ) {        for ( int I =0 ; I < 1000000; I++ )        {        // 判斷線程是否要被強制結束 /*  可能在這裡大家有點疑惑 ,如果沒有調用SetEvent() 的方法, hExitEvent 不是總處於未激髮狀態嗎?哪線程不就停在這裡不動了? 答案是:這裡用到了P74 提到的一個Wait….() 一個用法,當time_out 為0 ,檢查hExitEvent 的狀態,如果hExitEvent 處於未激髮狀態, 立刻返回WAIT_TIMEOUT ,如果hExitEvent 處於激髮狀態,則立刻 返回WAIT_OBJECT_0 。*/ if ( WaitForSingleObject ( hExitEvent , 0 ) !=WAIT_TIMEOUT ) {        // 做一些退出線程前的清理工作        return (DWORD) –1 ; }               // 做一些極其消耗時間的處理….               //…….               //……..        } } void main() {                           HANDLE hThrd; // 構造EVENT 核心對象, 初始狀態處於未激髮狀態,Manual 方式               hExitEvent = CreateEvent ( NULL,TRUE,FALSE,NULL ) ; // 線程啟動               hThrd = CreateThread ( null,ThreadFun,…..);               // 等待了很久,實在等不下去了,發出結束線程退出事件(激發EVENT 核心對象)               // 迫使線程結束               SetEvent ( hExitEvent ) ;        // 等待線程結束        WaitForSingleObject ( hThrd,… );        CloseHandle ( hThrd ); } 下面接著談到了線程的優先權,調整線程優先權很簡單,無非就是用SetThreadPriority()和GetThreadPriority()等函數。但如何有效,合理的調整線程的優先權卻是一個複雜的問題,正如書上所說,“如果你的目標是保持簡單,那就還是避免處理[優先權]這個燙山芋吧“。       附註:以上本文純屬加強記憶所做筆記,內容或有不詳,甚至錯誤,請閱者見諒,匆見怪!!!

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.