《CWin實(shí)踐開發(fā)教程》多線程編程技術(shù).ppt_第1頁
《CWin實(shí)踐開發(fā)教程》多線程編程技術(shù).ppt_第2頁
《CWin實(shí)踐開發(fā)教程》多線程編程技術(shù).ppt_第3頁
《CWin實(shí)踐開發(fā)教程》多線程編程技術(shù).ppt_第4頁
《CWin實(shí)踐開發(fā)教程》多線程編程技術(shù).ppt_第5頁
已閱讀5頁,還剩28頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、-基于C#語言,主講教師:錢 哨 本課學(xué)時(shí):72課時(shí) 聯(lián)系方式:,Windows程序設(shè)計(jì),第五章、多線程編程技術(shù),本章主要內(nèi)容介紹5.1 計(jì)算機(jī)線程介紹5.2 System.Threading簡介5.3 線程的優(yōu)先級與鎖技術(shù),CONTENT,本章學(xué)習(xí)目標(biāo):,理解線程的概念 理解.NET中線程的屬性和方法 創(chuàng)建和使用線程 理解線程的特點(diǎn)、優(yōu)點(diǎn)及使用場合,同時(shí)執(zhí)行所有任務(wù),時(shí)間更少,效率更高,5.1 線程簡介,讀 ,寫,一覽無遺,血液循環(huán),在同一時(shí)間點(diǎn)執(zhí)行各項(xiàng)進(jìn)程,編譯程序 發(fā)送/接收郵件 打印文件 其他,操作系統(tǒng)允許計(jì)算機(jī)同時(shí)執(zhí)行多項(xiàng)操作,程序 (進(jìn)程),5.1 線程簡介,程序 1,程序 2,線

2、程 1,線程 2,線程 3,線程 1,線程 2,線程 3,單獨(dú)的執(zhí)行路徑,多線程,5.1 線程簡介,進(jìn)程:是應(yīng)用程序的一個(gè)運(yùn)行例程,是應(yīng)用程序的一次動(dòng)態(tài)執(zhí)行過程。 線程:是進(jìn)程中的一個(gè)執(zhí)行單元;是操作系統(tǒng)分配CPU時(shí)間的基本單元。 Windows是一個(gè)支持多線程的系統(tǒng)。 一個(gè)進(jìn)程可以包含若干個(gè)線程。,5.1 線程簡介,在以下情況中可能要使用到多線程:,程序需要同時(shí)執(zhí)行兩個(gè)或多個(gè)任務(wù),程序要等待某事件的發(fā)生,例如用戶輸入、文件操作、網(wǎng)絡(luò)操作、搜索等,后臺(tái)程序,5.1 線程簡介,多線程:在同一時(shí)間執(zhí)行多個(gè)任務(wù)的功能,稱為多線程或自由線程。 多線程的優(yōu)點(diǎn):可以同時(shí)完成多個(gè)任務(wù);可以使程序的響應(yīng)速度更

3、快;可以讓占用大量處理時(shí)間的任務(wù)或當(dāng)前沒有進(jìn)行處理的任務(wù)定期將處理時(shí)間讓給別的任務(wù);可以隨時(shí)停止任務(wù);可以設(shè)置每個(gè)任務(wù)的優(yōu)先級以優(yōu)化程序性能。 多線程的缺點(diǎn): 對資源的共享訪問可能造成沖突(對共享資源的訪問進(jìn)行同步或控制) ;程序的整體運(yùn)行速度減慢等等。,在C#應(yīng)用程序中,第一個(gè)線程總是Main()方法,因?yàn)榈谝粋€(gè)線程是由.NET運(yùn)行庫開始執(zhí)行的,Main()方法是.NET運(yùn)行庫選擇的第一個(gè)方法。后續(xù)的線程由應(yīng)用程序在內(nèi)部啟動(dòng),即應(yīng)用程序可以創(chuàng)建和啟動(dòng)新的線程。,5.2 System.Threading 命名空間,5.2 System.Threading 命名空間,在.NET程序設(shè)計(jì)中,線程是

4、使用Thread類(或Timer類(線程計(jì)數(shù)器)、ThreadPool類(線程池)來處理的,這些類在System.Threading命名空間中: using System.Threading; Thread類:(實(shí)現(xiàn)線程的主要方法)一個(gè)Thread實(shí)例管理一個(gè)線程,即執(zhí)行序列。通過簡單實(shí)例化一個(gè)Thread對象,就可以創(chuàng)建一個(gè)線程,然后通過Thread對象提供的方法對線程進(jìn)行管理。 Timer類:適用于間隔性的完成任務(wù)。 ThreadPool類:適用于多個(gè)小的線程。,1、Thread 類的屬性和方法,引用System.Threading 命名空間,Thread 線程實(shí)例名 = new Thre

5、ad(new ThreadStart(方法名);,運(yùn)行在線程上的方法,只創(chuàng)建但不啟動(dòng)線程,線程實(shí)例名.Start();,1、Thread 類的屬性和方法,2、線程的生命周期,在 I/O 操作期間線程被阻止,線程已創(chuàng)建但并未啟動(dòng),線程已啟動(dòng),I/O 操作完成后運(yùn)行,線程被阻止,另一個(gè)操作正在進(jìn)行,提前中斷或特地停止線程,暫時(shí)中斷的線程,線程已恢復(fù),等待,/,休眠,/,加入,已暫停,正在運(yùn)行,已停止,未開始,已開始,已阻止,暫停,發(fā)送,I,/,O,請求,等待,,,休眠,,,加入,開始,I,/,O,完成,完成,恢復(fù),5.3 線程的建立與啟動(dòng),新建一個(gè)線程的過程:只需將其聲明并為其提供線程起始點(diǎn)處的方

6、法委托,再用Thread.Start()方法啟動(dòng)該線程 (1)聲明: Thread a; (2)實(shí)例化 a=new Thread(new ThreadStart(b); 其中,b為新建過程中執(zhí)行的過程名。 (3)調(diào)用Thread.Start()方法啟動(dòng)該線程 a.Start();,5.3 線程的建立與啟動(dòng),using System; using System.Threading; public class A public void ff()/線程啟動(dòng)時(shí)調(diào)用此方法 Console.WriteLine(A.ff()方法在另一個(gè)線程上運(yùn)行!); Thread.Sleep(3000);/將線程阻塞一

7、定時(shí)間 Console.WriteLine(終止工作線程調(diào)用此實(shí)例方法!); public static void gg() Console.WriteLine(A.gg()方法在另一個(gè)線程上運(yùn)行!); Thread.Sleep(5000);/將線程阻塞一定時(shí)間 Console.WriteLine(終止工作線程調(diào)用此靜態(tài)方法!); ,例題1:線程的建立和啟動(dòng),5.3 線程的建立與啟動(dòng),public class B public static void Main() Console.WriteLine(*線程簡單示例!*); A a=new A(); Thread s1=new Thread(n

8、ew ThreadStart(a.ff); s1.Start(); Console.WriteLine(啟動(dòng)新線程ff()方法后,被Main()線程調(diào)用!); Thread s2=new Thread(new ThreadStart(A.gg); s2.Start(); Console.WriteLine(啟動(dòng)新線程gg()方法后,被Main()線程調(diào)用!); Console.ReadLine(); ,例題1:線程的建立和啟動(dòng),5.3 線程的建立與啟動(dòng),線程的掛起(或暫停) (1)調(diào)用Thread.Sleep()方法將線程掛起。 注:Sleep()方法指定的時(shí)間以毫秒為單位。 (2)調(diào)用s1.

9、Suspend() 方法將線程掛起 區(qū)別:前者為靜態(tài)方法,并且使線程立即暫停一定時(shí)間;后者為實(shí)例方法,不會(huì)使線程立即停止執(zhí)行,直到線程到達(dá)安全點(diǎn)之后,它才將該線程暫停。 線程的恢復(fù)與終止 調(diào)用Resume()方法將線程恢復(fù); 調(diào)用Abort()方法將線程終止;,線程的掛起、恢復(fù)與終止,其他與操作線程相關(guān)的方法,Join():使一個(gè)線程等待另一個(gè)線程停止 Interrupt():中斷處于JoinWaitSleep線程狀態(tài)的線程。,5.4 線程的優(yōu)先級,class SimpleThreadDemo static void Main(string args) Thread.CurrentThread

10、.Name = “主線程; Thread objThread = new Thread(new ThreadStart(ActionMethod); objThread.Name = “子線程; /啟動(dòng)子線程, 并為該線程執(zhí)行 ActionMethod objThread.Start(); /這將為主線程執(zhí)行 ActionMethod ActionMethod(); static void ActionMethod() for(int count = 1; count = 10 ; count+) Console.WriteLine(“線程名: + Thread.CurrentThread.N

11、ame); ,實(shí)例化 objThread 線程并開始執(zhí)行 ActionMethod(),將由應(yīng)用程序線程執(zhí)行,輸出結(jié)果混亂,5.4 線程的優(yōu)先級,線程是根據(jù)其優(yōu)先級來調(diào)度的,每個(gè)線程都有特定的優(yōu)先級。每個(gè)線程在創(chuàng)建時(shí)其優(yōu)先級為: ThreadPriority . Normal 線程的優(yōu)先級定義為ThreadPriority枚舉類型,如下表:,5.4 線程的優(yōu)先級,例題1:,static void TaskTwo() for(int index = 5000;index =4990; index-) Console.WriteLine(index); ,static void Main(stri

12、ng args) Thread objThreadOne = new Thread(new ThreadStart(TaskOne); Thread objThreadTwo = new Thread(new ThreadStart(TaskTwo); objThreadOne.Start(); objThreadTwo.Start(); ,static void TaskOne() for(int count=1;count=5;count+) Console.WriteLine(count*2); ,無優(yōu)先級線程,同時(shí)執(zhí)行,輸出無序.,例題1:,static void Main(strin

13、g args) Thread.CurrentThread.Name = “主線程; Thread objThreadOne = new Thread(new ThreadStart(TaskOne); objThreadOne.Name = “子線程 1; Thread objThreadTwo = new Thread(new ThreadStart(TaskTwo); objThreadTwo.Name = “子線程 2; / 這將啟動(dòng)子線程 objThreadOne.Start(); objThreadTwo.Start(); objThreadTwo.Priority = Thread

14、Priority.Highest; ,將在執(zhí)行第一個(gè)線程前執(zhí)行 objThreadTwo,5.4 線程的優(yōu)先級,5.4 線程的優(yōu)先級,【代碼見下:】 問題:請將代碼執(zhí)行多次,觀察每次執(zhí)行順序的不同之處。 為什么代碼執(zhí)行是完全不同呢? 【結(jié)論:】 如果不將線程按照一定的順序運(yùn)行,則線程代碼在處理上將會(huì)混亂不堪。,例題2:使用三個(gè)線程顯示計(jì)數(shù),5.4 線程的優(yōu)先級,【線程優(yōu)先級小結(jié):】 如果自行提高一個(gè)線程的優(yōu)先級,那么該線程就會(huì)相應(yīng)的獲得更多的CPU時(shí)間;通過降低了線程的優(yōu)先級,該線程就會(huì)被分配到比原來少的CPU時(shí)間了。 你可以在一個(gè)線程開始運(yùn)行前或是在它的運(yùn)行過程中的任何時(shí)候改變它的優(yōu)先級。理

15、論上你還可以任意的設(shè)置每個(gè)線程的優(yōu)先級,不過一個(gè)優(yōu)先級過高的線程往往會(huì)影響到其他線程的運(yùn)行,甚至影響到其他程序的運(yùn)行,所以最好不要隨意的設(shè)置線程的優(yōu)先級。,例題1:使用三個(gè)線程顯示計(jì)數(shù)【代碼更改】,5.5 線程的同步,使用線程的一個(gè)重要方面是同步訪問多個(gè)線程訪問的任何變量。 背景:當(dāng)多個(gè)線程共享數(shù)據(jù),其中一個(gè)或多個(gè)線程要修改數(shù)據(jù)時(shí),有可能引起數(shù)據(jù)不統(tǒng)一等問題。 同步:是指在某一時(shí)刻只有一個(gè)線程可以訪問某共享數(shù)據(jù)。 1、同步的含義 同步問題的產(chǎn)生,主要是由于在高級語言的源代碼中,大多數(shù)情況下看起來是一條語句,但在最后編譯好的匯編語言機(jī)器碼中則會(huì)被翻譯為許多條語句,從而在操作系統(tǒng)調(diào)度時(shí)被劃分到不同

16、的時(shí)間片中。 例如,5.5 線程的同步,例如: message += Hello world!; 這條語句在C#語法上是一條語句,但在執(zhí)行代碼時(shí),實(shí)際上它涉及到許多操作。需要重新分配內(nèi)存以存儲(chǔ)更長的新字符串,需要設(shè)置變量message使之指向新的內(nèi)存,需要復(fù)制實(shí)際文本等。,5.5 線程的同步,通過對指定對象的加鎖和解鎖可以實(shí)現(xiàn)同步代碼段的訪問。 在.NET的System.Threading命名空間中提供了Monitor類來實(shí)現(xiàn)加鎖與解鎖。該類中的方法都是靜態(tài)的。如下表:,1、在C#中處理同步,鎖定機(jī)制,程序,線程1,線程2,共享資源,鎖定機(jī)制保證每次只有一個(gè)線程可以訪問共享資源,緩沖和隔離,示

17、例,class ThreadLockDemo static void Main() Thread.CurrentThread.Name = “主線程; ThreadLockDemo objDemo = new ThreadLockDemo(); Thread newThread = new Thread (new ThreadStart(objDemo.DoTask); newThread.Name = “子線程; newThread.Start(); objDemo.DoTask(); void DoTask() lock(this) for(int count = 1; count = 1

18、0 ; count+) Console.WriteLine(“線程名: + Thread.CurrentThread.Name); ,實(shí)例化 newThread 線程并開始執(zhí)行 DoTask(),鎖定當(dāng)前實(shí)例 objDemo,在塊中完成執(zhí)行,然后釋放對象,5.5 線程的同步,C#中 lock關(guān)鍵字提供了與Monitoy.Enter和Monitoy.Exit同樣的功能,這種方法用在你的代碼段不能被其他獨(dú)立的線程中斷的情況。通過對Monitor類的簡易封裝,lock為同步訪問變量提供了一個(gè)非常簡單的方式,其用法如下: lock(x) / 使用x的語句 ,1、在C#中處理同步,lock語句把變量放在圓括號中,以包裝對象,稱為獨(dú)占鎖或排它鎖。當(dāng)執(zhí)行帶有l(wèi)ock關(guān)鍵字的復(fù)合語句時(shí),獨(dú)占鎖會(huì)保留下來。當(dāng)變量被包裝在獨(dú)占鎖中時(shí),其他線程就不能訪問該變量。如果在上面的代碼中使用獨(dú)占鎖,在執(zhí)行復(fù)合語句時(shí),這個(gè)線程就會(huì)失去其時(shí)間片。如果下一個(gè)獲得時(shí)間片的線程試

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論