線程間的同步概述1.前言前面幾篇文章著重介紹了多線程的三種創(chuàng)建方式及多線程間的4種通信方式,并采用大量的實(shí)例演示,相信大家對線程的創(chuàng)建和使用有了一定的了解。若還不了解請復(fù)習(xí)下前面的文章,多動手寫代碼和調(diào)試,光看不練,假把式。 今天先請大家看看下面一個多線程程序,操作很簡單,就是創(chuàng)建9個線程,并輸出相應(yīng)的線程編號(即報(bào)數(shù))。主要代碼如下:
當(dāng)運(yùn)行一次OnBnClickedButton1()函數(shù),將顯示下面的結(jié)果:
你一看,沒錯呀,就應(yīng)該是這樣的,沒有錯呀!多運(yùn)行幾次也是這樣的。但我要肯定的告訴你,上面的程序是有嚴(yán)重的問題,而運(yùn)行結(jié)果也欺騙了你。正是運(yùn)行結(jié)果大大蒙騙了你的理智和大腦。你發(fā)現(xiàn)問題了嗎?(提示:不是報(bào)數(shù)順序的問題) 正是該錯誤有隱蔽性,你很難從結(jié)果中發(fā)現(xiàn)問題,除非你運(yùn)氣特別好,一運(yùn)行就能重現(xiàn)問題,但作為程序員,你決不能僅靠運(yùn)氣,不可能你每次的運(yùn)氣都這么好。 多運(yùn)行幾次上面的程序,你有可能發(fā)現(xiàn)問題,現(xiàn)在我把該程序改進(jìn)下,使其具有自動識別錯誤的智能,你一眼就能發(fā)現(xiàn)問題的。 改進(jìn)點(diǎn):添加結(jié)果檢測功能,若正常,其線程的報(bào)數(shù)應(yīng)該為1-9,有可能順序有變,但總和為45=1+2+3+4+5+6+7+8+9。程序?qū)⒁恢毖h(huán)到程序退出。若不等于45就退出循環(huán),表示有問題,即讓程序一直運(yùn)行,直到有錯誤為止。前面的OnBnClickedButton1()函數(shù)和ThreadFunc()函數(shù)保存不變,WaitThread()函數(shù)添加一個判斷語句,改進(jìn)程序如下:
再運(yùn)行上面的程序,選中“自動判斷”,程序?qū)⒑芸觳煌5倪\(yùn)行,但很快將又停下來,運(yùn)行結(jié)果如下圖所示,有可能你的結(jié)果和我的不一樣,但類型差不多的。
工程源碼下載:http://download.csdn.net/detail/cbnotes/5015914 現(xiàn)在你發(fā)現(xiàn)問題了嗎?對了,報(bào)數(shù)出現(xiàn)相同數(shù)了(見上圖出現(xiàn)兩個“2”)。 你可能要問,怎么會這樣呢? 這就是多線程最容易出現(xiàn)的問題,也是多線程編程的難點(diǎn)和核心。再說說上面程序,創(chuàng)建了9個線程,這9個線程是同時(shí)運(yùn)行的(即并行運(yùn)行),它們都要修改變量全局g_nCount(g_nCount++;),就有可能兩個或多個線程同時(shí)讀取到g_nCount,而當(dāng)前的g_nCount已經(jīng)被其它線程修改,即輸出的不是線程當(dāng)前的值。這和單線程的順序執(zhí)行是有很大不同的。 那有什么方法解決上面的問題嗎?當(dāng)然有,這就是在江湖中大名鼎鼎的線程同步技術(shù),而且系統(tǒng)提供了多種線程同步的技術(shù)/方法。 2.什么是同步“同步”不是指平常所說的兩件事情同時(shí)進(jìn)行。它的目的是使多個線程之間協(xié)調(diào)工作,而且常常是避免兩個線程同時(shí)進(jìn)行某些操作,比如同時(shí)訪問同一個共享資源。一般來說,同步是通過暫時(shí)將會發(fā)生沖突操作的某個線程暫停執(zhí)行(稱為阻塞線程),然后等待不會沖突時(shí)再繼續(xù)執(zhí)行。 3.需要同步的情況3.1、多個線程同時(shí)訪問同一對象時(shí)MFC對象在對象級不是線程安全的,只有在類級才是。如:兩個線程可以安全地使用兩個不同的CString對象,但同時(shí)使用同一個CString對象就可能產(chǎn)生問題。如果必須使用同一個對象,那么應(yīng)該采取適當(dāng)?shù)耐交胧?/p> 3.2、多個線程之間需要協(xié)調(diào)運(yùn)行例如,如果第二個線程需要等待第一個線程完成到某一步時(shí)才能運(yùn)行,那么該線程應(yīng)該暫時(shí)掛起以減少對CPU的占用時(shí)間,提高程序的執(zhí)行效率。當(dāng)?shù)谝粋€線程完成了相應(yīng)的步驟后,應(yīng)該發(fā)出某種信號來激活第二個線程。 4.Windows中的4種線程同步技術(shù)4.1、Events(事件)——CEvent作為標(biāo)志在線程之間傳遞信號。簡單地說,類似一個布爾型變量的開關(guān)作用。 4.2、Critical Sections(臨界段)——CCriticalSection在進(jìn)程中作為關(guān)鍵字以獲得對共享資源的訪問 4.3、Mutexes(互斥量)——CMutex與臨界段的工作方式相似,只是該對象可以用于多進(jìn)程中的線程同步,而不是用于單進(jìn)程中 4.4、Semaphores(信號量)——CSemaphore在給定的限制條件下,允許多個進(jìn)程同時(shí)訪問共享資源 關(guān)于這四種同步方法/技術(shù)我將一個一個給大家介紹和實(shí)例演示,歡迎大家繼續(xù)關(guān)注。 ===================================================== 轉(zhuǎn)載請標(biāo)明出處,謝謝。http://blog.csdn.net/cbNotes =====================================================
|
|
|