版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
2013.07第6章進(jìn)程與線程開發(fā)程序設(shè)計(jì)
學(xué)習(xí)要點(diǎn)1.了解進(jìn)程與線程的基本技術(shù)2.掌握C#進(jìn)程應(yīng)用程序開發(fā)方法3.掌握C#常用多線程互斥與同步的應(yīng)用程序開發(fā)方法4.掌握C#跨線程訪問控件的基本方法6.1進(jìn)程與線程概述1.進(jìn)程
Windows是一個(gè)多任務(wù)的系統(tǒng),它能夠同時(shí)運(yùn)行多個(gè)程序,其中的每一個(gè)正在運(yùn)行的程序就稱為一個(gè)“進(jìn)程”。Windows2000及其以上版本,可以通過任務(wù)管理器查看系統(tǒng)當(dāng)前運(yùn)行的程序和進(jìn)程。2.線程對(duì)于同一個(gè)進(jìn)程,又可以分成若干個(gè)獨(dú)立的執(zhí)行流,這樣的流則被稱為“線程”。線程是操作系統(tǒng)向其分配處理器時(shí)間的基本單位,它可以獨(dú)立占用處理器的時(shí)間片,同一進(jìn)程中的線程可以共享其進(jìn)程的資源和內(nèi)存空間。每一個(gè)進(jìn)程至少包含一個(gè)線程。3.并發(fā)進(jìn)程和線程技術(shù)的引入,為實(shí)現(xiàn)系統(tǒng)或應(yīng)用程序的并行性提供了重要的技術(shù)基礎(chǔ)。所謂的“并行”又被稱為“并發(fā)”,是指系統(tǒng)或應(yīng)用程序同時(shí)處理多個(gè)事務(wù)的運(yùn)行過程。對(duì)于單處理器的計(jì)算機(jī)系統(tǒng)來說,由于單個(gè)CPU在任何時(shí)刻只能執(zhí)行一個(gè)線程,所以,這種計(jì)算機(jī)系統(tǒng)的并發(fā),實(shí)際上是通過操作系統(tǒng)在各個(gè)正在執(zhí)行的線程之間切換CPU,以分時(shí)處理的方式實(shí)現(xiàn)表面形式上的并發(fā),只是因?yàn)槠淝袚Q的速度快且處理能力強(qiáng)時(shí),用戶直觀感覺不到而已。當(dāng)然,對(duì)于多處理器的計(jì)算機(jī)系統(tǒng),其多個(gè)CPU之間既有相互協(xié)作,又有獨(dú)立分工,所以,它們?cè)诟髯詧?zhí)行一個(gè)相應(yīng)線程時(shí)可以互不影響,同時(shí)進(jìn)行,進(jìn)而實(shí)現(xiàn)真正意義上的并發(fā)處理。6.2進(jìn)程開發(fā)技術(shù)
進(jìn)程與程序不同,它是程序執(zhí)行時(shí)的標(biāo)志,而不是程序的靜態(tài)版本。用戶創(chuàng)建一個(gè)進(jìn)程后,操作系統(tǒng)就將程序的一個(gè)副本裝入計(jì)算機(jī)中,然后啟動(dòng)一個(gè)線程執(zhí)行該程序。盡管.NET環(huán)境中仍然使用進(jìn)程和線程,但管理代碼的應(yīng)用程序邊界是應(yīng)用程序域。通用語言運(yùn)行庫(CLR)強(qiáng)制隔離應(yīng)用程序域,使一個(gè)進(jìn)程中可以有多個(gè)隔離的應(yīng)用程序。在C#中,可通過兩種方法來開發(fā)進(jìn)程程序:C#的System.Diagnostics命名空間下的Process類專門用于完成系統(tǒng)的進(jìn)程管理任務(wù),通過實(shí)例化一個(gè)Process類,就可以啟動(dòng)一個(gè)獨(dú)立進(jìn)程。C#的進(jìn)程組件(Process)提供了對(duì)本地和遠(yuǎn)程進(jìn)程的訪問功能,并啟用本地進(jìn)程的開始和停止功能。6.2進(jìn)程開發(fā)技術(shù)開發(fā)一個(gè)利用進(jìn)程控制應(yīng)用程序的設(shè)計(jì)示例。通過點(diǎn)擊相應(yīng)的按鈕,既能方便地打開Windows操作系統(tǒng)附件中的“計(jì)算器”或此前開發(fā)的“上機(jī)自測(cè)系統(tǒng)”,也能將它們隨時(shí)關(guān)閉?!臼纠a:chpt6-2\CProcess】(1)新建一個(gè)C#項(xiàng)目,其Windows應(yīng)用程序命名為CProcess,并從“公共組件”工具箱中拖放相應(yīng)控件到新建窗體Form1上。(2)按照表所示的內(nèi)容,設(shè)置各控件的相應(yīng)屬性值??丶∟ame)屬性屬性新值button1NamebtnCalculatorStartText啟動(dòng)一個(gè)計(jì)算器button2NamebtnCalculatorStopAllText關(guān)閉全部計(jì)算器button3NamebtnSelfExamStartText啟動(dòng)一個(gè)上機(jī)自測(cè)系統(tǒng)button4NamebtnSelfExamStopAllText關(guān)閉全部上機(jī)自測(cè)系統(tǒng)6.2進(jìn)程開發(fā)技術(shù)(3)從“組件”工具箱中拖放1個(gè)Process組件到該窗體上,并將它們的Text屬性分別設(shè)置為CalculatorProcess。(4)首先,從Windows操作系統(tǒng)的“開始”→“所有程序”→“附件”→右鍵點(diǎn)擊“計(jì)算器”,打開“快捷方式”屬性對(duì)話框,如圖6-2所示,將其“目標(biāo)”文件及其前面的“\”合并至“起始位置”之后,拷貝全部“起始位置”內(nèi)容,并點(diǎn)擊“取消”關(guān)閉計(jì)算器屬性面板。利用進(jìn)程控制應(yīng)用程序設(shè)置進(jìn)程啟動(dòng)信息6.2進(jìn)程開發(fā)技術(shù)(5)分別編寫通過C#進(jìn)程組件啟動(dòng)和關(guān)閉計(jì)算器的相應(yīng)代碼。usingSystem.Diagnostics;usingSystem.Threading;//啟動(dòng)一個(gè)Windows計(jì)算器privatevoidbtnCalculatorStart_Click(objectsender,EventArgse){CalculatorProcess.Start();}//關(guān)閉全部已啟動(dòng)的Windows計(jì)算器privatevoidbtnCalculatorStopAll_Click(objectsender,EventArgse){//創(chuàng)建一個(gè)Process組件的數(shù)組
Process[]CalculatorProcess;//將所建數(shù)組與指定進(jìn)程名稱(calc)的所有進(jìn)程資源相關(guān)聯(lián)
CalculatorProcess=Process.GetProcessesByName("calc");//遍歷當(dāng)前啟動(dòng)程序中,查找包含指定名稱的進(jìn)程
foreach(ProcessinstanceinCalculatorProcess){//終止當(dāng)前進(jìn)程,關(guān)閉應(yīng)用程序窗體
instance.CloseMainWindow();}}6.2進(jìn)程開發(fā)技術(shù)(6)分別編寫通過實(shí)例化一個(gè)C#的Process類,啟動(dòng)和關(guān)閉上機(jī)自測(cè)系統(tǒng)的相應(yīng)代碼。usingSystem.IO;//啟動(dòng)一個(gè)上機(jī)自測(cè)系統(tǒng)privatevoidbtnSelfExamStart_Click(objectsender,EventArgse){FileInfofInfo=newFileInfo(@"E:\C#程序設(shè)計(jì)\教材源代碼
\chpt5-1\selfExam\selfExam\bin\Debug\selfExam.exe");if(fInfo.Exists){//實(shí)例一個(gè)Process類,啟動(dòng)一個(gè)獨(dú)立進(jìn)程
ProcessprcsSelfExam=newProcess();//Process有一個(gè)StartInfo屬性,這是ProcessStartInfo類,包括一些 方法和屬性
//待啟動(dòng)的程序文件
prcsSelfExam.StartInfo.FileName=fInfo.FullName;//啟動(dòng)進(jìn)程
prcsSelfExam.Start();}else{MessageBox.Show("文件:"+fInfo.FullName+"不存在!");}}6.2進(jìn)程開發(fā)技術(shù)//關(guān)閉已啟動(dòng)的所有上機(jī)自測(cè)系統(tǒng){//創(chuàng)建一個(gè)Process組件的數(shù)組
Process[]SelfExamProcess;//將所建數(shù)組與指定進(jìn)程名稱(selfExam)的所有進(jìn)程資源相關(guān)聯(lián)
SelfExamProcess=Process.GetProcessesByName("selfExam");//遍歷當(dāng)前啟動(dòng)程序中,查找包含指定名稱的進(jìn)程
foreach(ProcessinstanceinSelfExamProcess){//終止當(dāng)前進(jìn)程,關(guān)閉應(yīng)用程序窗體
instance.CloseMainWindow();}}6.3線程開發(fā)基礎(chǔ)知識(shí)1.線程的引入你的銀行賬戶余額為:100,000同時(shí)有兩個(gè)人在給你匯款:50,000第一個(gè)人從數(shù)據(jù)庫中把你的余額讀出來:100,000第一個(gè)人把你的余額修改成:150,000第二個(gè)人從數(shù)據(jù)庫中把你的余額讀出來:100,000第二個(gè)人把你的余額修改成:150,000第一個(gè)人把你的余額存入數(shù)據(jù)庫:150,000第二個(gè)人把你的余額存入數(shù)據(jù)庫:150,000有5,000不翼而飛了?2.命名空間引用
.NET將關(guān)于多線程的功能定義在System.Threading命名空間中。因此,要使用多線程,必須先引用此命名空間(usingSystem.Threading;)。在這個(gè)命名空間下,包含了用于創(chuàng)建和控制線程的類Thread。一個(gè)Thread的實(shí)例表示一個(gè)線程,也就是一個(gè)執(zhí)行序列。通過實(shí)例化一個(gè)Thread對(duì)象,就可以創(chuàng)建一個(gè)線程。6.3線程開發(fā)基礎(chǔ)知識(shí)2.線程創(chuàng)建與控制在System.Threading.Thread類中,包含了以下幾種方法,用于創(chuàng)建和控制線程:創(chuàng)建線程在C#中使用Thread類創(chuàng)建線程時(shí),只需提供線程入口即可(線程入口使程序知道該讓這個(gè)線程去做什么)。線程入口是通過ThreadStart代理(delegate)來提供的,我們可以把ThreadStart理解為一個(gè)函數(shù)指針,指向線程要執(zhí)行的函數(shù),示例代碼如下:Threadthread1=newThread(newThreadStart(Method1));啟動(dòng)線程顧名思義,“啟動(dòng)線程”就是并啟動(dòng)一個(gè)新建的線程。當(dāng)調(diào)用C#的Start()方法后,線程就開始執(zhí)行ThreadStart所代表或者說指向的函數(shù),示例代碼如下:
thread1.Start();
其中的Method1是將要被新線程執(zhí)行的函數(shù)。6.3線程開發(fā)基礎(chǔ)知識(shí)銷毀線程因?yàn)橛?jì)算機(jī)的資源是有限的,所以,當(dāng)一個(gè)線程的任務(wù)完成后,如果此后將不再被使用它,就應(yīng)及時(shí)釋放它所占用的系統(tǒng)內(nèi)存,也即銷毀它。通過調(diào)用Abort()方法銷毀一個(gè)線程。所以,為了不徒勞去銷毀一個(gè)非活線程,在銷毀一個(gè)線程之前通常先利用IsAlive屬性來判斷它是否還處于活動(dòng)狀態(tài),而后再采取銷毀措施,示例代碼如下:if(thread1.IsAlive==true){thread1.Abort();}休眠線程開發(fā)線程時(shí),有時(shí)不希望它一直連續(xù)運(yùn)行,而是以一定的周期運(yùn)行,或者想讓它延遲一段時(shí)間,以等待其他線程運(yùn)行,這時(shí)可利用Sleep()方法,將“當(dāng)前線程”臨時(shí)終止或休眠一段時(shí)間(毫秒)。如Thread.Sleep(1000);就是讓線程休眠1秒鐘。6.3線程開發(fā)基礎(chǔ)知識(shí)掛起線程Suspend()方法用來掛起一個(gè)正在運(yùn)行的線程,直到調(diào)用Resume()方法,此線程才可以繼續(xù)執(zhí)行。如果線程已掛起,則此方法不起作用,所以,在準(zhǔn)備執(zhí)行線程掛起操作之前,先要判斷其當(dāng)前是否處于運(yùn)行狀態(tài),示例代碼如下:if(thread1.ThreadState=ThreadState.Running)
{
thread1.Suspend();
}恢復(fù)線程Resume()方法用來恢復(fù)已經(jīng)掛起的線程,以讓它繼續(xù)執(zhí)行,但若線程并未掛起,則此方法不會(huì)起作用,所以,在準(zhǔn)備執(zhí)行線程掛起操作之前,先要判斷其當(dāng)前是否處于掛起狀態(tài),示例代碼如下:if(thread1.ThreadState=ThreadState.Suspended)
{
thread1.Resume();}終止線程Thread.Interrupt()用來終止處于Wait、Sleep或者Join狀態(tài)的線程。阻塞線程Join()用來阻塞調(diào)用線程,直到某個(gè)線程終止時(shí)為止。6.3線程開發(fā)基礎(chǔ)知識(shí)3.Thread的公共屬性屬性名稱說明ApartmentState獲取或設(shè)置線程的單元狀態(tài)CurrentContext獲取線程正在執(zhí)行的當(dāng)前上下文CurrentCulture獲取或設(shè)置線程的區(qū)域性CurrentPrincipal獲取或設(shè)置線程當(dāng)前負(fù)責(zé)人CurrentThread獲取當(dāng)前正在運(yùn)行的線程CurrentUICulture獲取或設(shè)置資源管理器使用的當(dāng)前區(qū)域性IsAlive獲取一個(gè)值,該值指示當(dāng)前線程的執(zhí)行狀態(tài)。如果此線程已啟動(dòng)并且尚未正常終止或中止,則為true;否則為falseIsBackGround獲取或設(shè)置一個(gè)值,該值指示某個(gè)線程是否為后臺(tái)線程IsThreasPoolThread判斷是否是線程池線程N(yùn)ame獲取或設(shè)置線程名稱Priority獲取或設(shè)置一個(gè)值,該值指示線程的調(diào)度優(yōu)先級(jí)ThreadState獲取一個(gè)值,該值包含當(dāng)前線程的狀態(tài)6.3線程開發(fā)基礎(chǔ)知識(shí)4.ThreadState屬性:屬性值說明Aborted線程已停止AbortRequested線程的Thread.Abort()方法已被調(diào)用,但是線程還未停止Background線程在后臺(tái)執(zhí)行,與屬性Thread.IsBackground有關(guān);不妨礙程序的終止Running線程正在正常運(yùn)行Stopped線程已被停止StopRequested線程正在被要求停止Suspended線程已被掛起(此狀態(tài)下,可以通過調(diào)用Resume()方法重新運(yùn)行)SuspendRequested線程正在要求被掛起,但是未來得及響應(yīng)Unstarted未調(diào)用Thread.Start()開始線程的運(yùn)行WaitSleepJoin線程因調(diào)用了Wait()、Sleep()或Join()等方法處于封鎖狀態(tài)6.3線程開發(fā)基礎(chǔ)知識(shí)5.線程優(yōu)先級(jí)在C#中,一個(gè)線程的優(yōu)先級(jí)由高到低可分為5種:Highest、AboveNormal、Normal、BelowNormal和Lowest。對(duì)于新創(chuàng)建但未指定優(yōu)先級(jí)的線程,系統(tǒng)默認(rèn)設(shè)置其優(yōu)先級(jí)為Normal。示例代碼如下://將線程的優(yōu)先級(jí)設(shè)置為最高優(yōu)先級(jí)
thread1.Priority=ThreadPriority.Highest;6.3線程開發(fā)基礎(chǔ)知識(shí)6.示例程序設(shè)計(jì)在應(yīng)用程序開發(fā)過程中經(jīng)常會(huì)遇到線程的例子,例如,某個(gè)后臺(tái)操作比較費(fèi)時(shí)間,我們就可以啟動(dòng)一個(gè)線程去執(zhí)行這個(gè)費(fèi)時(shí)的操作,同時(shí)仍可使當(dāng)前程序繼續(xù)執(zhí)行。以下是一個(gè)簡(jiǎn)單的線程應(yīng)用程序開發(fā)示例,在這個(gè)程序中,有兩個(gè)相互獨(dú)立的線程,各自進(jìn)行0~999的累加計(jì)數(shù)并顯示,每次計(jì)數(shù)到最大值(999)時(shí),將暫停3秒,而后又重新開始0~999的計(jì)數(shù)和顯示。在此期間,如果按下“終止線程”按鈕,計(jì)數(shù)將停止;否則,上述過程將循環(huán)往復(fù)?!臼纠a:chpt6-3a\MThreadTest1】6.4多線程開發(fā)技術(shù)6.4.1多線程概述實(shí)際上,在上一節(jié)的線程開發(fā)示例(chpt6-3a)中,就包含了多個(gè)線程(兩個(gè)線程分別實(shí)現(xiàn)累加計(jì)數(shù)的功能)。1.多線程所謂多線程,是指程序中包含多個(gè)執(zhí)行流,即在一個(gè)程序中可以同時(shí)運(yùn)行多個(gè)不同的線程來執(zhí)行不同的任務(wù),也就是說允許單個(gè)程序創(chuàng)建多個(gè)并行執(zhí)行的線程來完成各自的任務(wù)。瀏覽器就是一個(gè)典型的多線程的例子,在瀏覽器中,你可以在下載文件的同時(shí)滾動(dòng)頁面,也可在打開一個(gè)新頁面的同時(shí)播放動(dòng)畫和聲音,甚至同時(shí)打印網(wǎng)頁等。2.多線程的好處多線程的好處在于可以提高CPU的利用率,因?yàn)椋诙嗑€程程序中,一個(gè)線程必須等待的時(shí)候,CPU可以運(yùn)行其它的線程而不是等待,這樣就大大提高了程序的效率。6.4多線程開發(fā)技術(shù)3.多線程的不利然而我們也必須認(rèn)識(shí)到線程本身可能影響系統(tǒng)性能的不利方面,這些方面主要包括:線程也是程序,所以線程需要占用內(nèi)存,線程越多占用內(nèi)存也越多。多線程需要協(xié)調(diào)和管理,所以需要CPU時(shí)間跟蹤線程。線程之間對(duì)共享資源的訪問會(huì)相互影響,必須解決競(jìng)用共享資源的問題。線程太多會(huì)導(dǎo)致控制太復(fù)雜,最終可能造成很多Bug。6.4.2多線程互斥與同步概述1.多線程互斥在多線程的應(yīng)用程序中,由于受資源的有限性限制,或者為了避免多個(gè)線程同時(shí)訪問共享資源而產(chǎn)生信息處理矛盾或錯(cuò)誤,必須采取排他性的資源訪問方式一次只允許一個(gè)線程對(duì)其進(jìn)行訪問共享的資源,就是多線程的互斥。互斥無法限制線程對(duì)資源的訪問順序,即訪問是無序的。2.多線程同步在多線程的應(yīng)用程序中,多個(gè)線程之間可能需要相互協(xié)作,以便共同完成相應(yīng)的任務(wù),即某些線程需要其他線程提供的資源,或反之。這種多個(gè)線程之間相互配合、協(xié)同工作的方式,就是多線程的同步。通常情況下,同步已經(jīng)實(shí)現(xiàn)了互斥,特別是所有寫入資源的情況必定是互斥的。少數(shù)情況是指可以允許多個(gè)線程同時(shí)訪問資源。6.4.3多線程互斥程序開發(fā)在C#中,可以利用Lock關(guān)鍵字、Monitor類(監(jiān)視器)、Mutex類(互斥器)以及ReaderWriterLock類等多種方法實(shí)現(xiàn)多線程的互斥。1.lock:一般用于多個(gè)線程共享同一個(gè)代碼段的情況概述lock是C#中的關(guān)鍵字,它將語句塊標(biāo)記為一個(gè)臨界區(qū),確保當(dāng)一個(gè)線程位于代碼的臨界區(qū)時(shí),另一個(gè)線程不進(jìn)入臨界區(qū)。如果其他線程試圖進(jìn)入鎖定的代碼,則它將一直等待(即被阻止),直到該對(duì)象被釋放。其執(zhí)行過程是先獲得給定對(duì)象的互斥鎖,然后執(zhí)行相應(yīng)語句,任務(wù)完成后再釋放該鎖。通常應(yīng)避免鎖定public類型的對(duì)象,否則實(shí)例將超出代碼的控制范圍。最佳做法是定義private對(duì)象來鎖定,或privatestatic對(duì)象變量來保護(hù)所有實(shí)例所共有的數(shù)據(jù)。用法關(guān)鍵字lock定義如下:lock(object)@//互斥段的代碼Statement_Block或者:lock(object){@//互斥段的代碼DoSomething();……}6.4.3多線程互斥程序開發(fā)示例程序設(shè)計(jì)在此示例中,當(dāng)點(diǎn)擊“啟動(dòng)線程”按鈕后,程序?qū)⑼ㄟ^兩個(gè)線程同時(shí)向同一個(gè)文本框分別寫入字符a和A,而當(dāng)點(diǎn)擊“停止線程”按鈕后,寫入過程將隨時(shí)停止。顯然,這個(gè)共用的文本框就相當(dāng)于一個(gè)共享資源,程序執(zhí)行過程中如果不運(yùn)用必要的線程互斥技術(shù),將可能出現(xiàn)訪問沖突或數(shù)據(jù)處理錯(cuò)誤的問題,為此,必須運(yùn)用必要的線程互斥技術(shù)。【示例代碼:chpt6-4a\ThreadMutex1】(詳細(xì)代碼見教材)6.4.3多線程互斥程序開發(fā)2.Monitor:靜態(tài)類,一般用于多個(gè)線程之間進(jìn)行同步概述Monitor提供了與lock類似的功能,它通過向單個(gè)線程授予對(duì)象鎖來控制對(duì)該對(duì)象的訪問。用法Monitor類的2個(gè)常用方法如表所示。除此之外,還有以下方法:Wait:釋放對(duì)象上的鎖并阻塞當(dāng)前線程,直到它重新獲取該鎖Pulse(object)/PulseAll(object):向阻塞線程隊(duì)列(由于該object而轉(zhuǎn)入阻塞狀態(tài)的所有線程,也就是那些執(zhí)行了Wait(object)的線程,存放的隊(duì)列)中第一個(gè)/所有線程發(fā)信號(hào),該信號(hào)通知鎖定對(duì)象的狀態(tài)已更改,并且鎖的所有者準(zhǔn)備釋放該鎖。收到信號(hào)的阻塞線程進(jìn)入就緒隊(duì)列中,以便它有機(jī)會(huì)接收對(duì)象鎖。注意,接受到信號(hào)的線程只會(huì)從阻塞中被喚醒,并不一定會(huì)獲得對(duì)象鎖方法說明Enter()在指定對(duì)象上獲取排他鎖Exit()釋放指定對(duì)象上的排他鎖注意:以上所有方法都只能在臨界區(qū)內(nèi)被調(diào)用,換句話說,只有對(duì)象鎖的獲得者能夠正確調(diào)用它們,否則會(huì)引發(fā)SynchronizationLockException異常。
注意:如果Exit和Enter函數(shù)的調(diào)用次數(shù)不匹配,則該鎖不會(huì)被正確釋放。
6.4.3多線程互斥程序開發(fā)Monitor類的基本用法如下://obj是一個(gè)private級(jí)的內(nèi)部變量,不表示任何意義,只是作為一種“令牌”//的角色。如果要鎖定一個(gè)類的實(shí)例,可以使用thisprivateSystem.Objectobj=newobject();…System.Threading.Monitor.Enter(obj);try{//互斥段的代碼DoSomething();……}//對(duì)象非正常釋放catch(ThreadAbortException等異常){System.Threading.Monitor.Exit(obj);}//對(duì)象正常釋放System.Threading.Monitor.Exit(obj);6.4.3多線程互斥程序開發(fā)示例程序設(shè)計(jì)說明:在此,仍然設(shè)計(jì)一個(gè)chpt6-4a所示功能的示例。【示例代碼:chpt6-4b\MThreadTest1】設(shè)計(jì)步驟如下:(1)復(fù)制項(xiàng)目文件夾chpt6-4a,并將其重新命名為chpt6-4b。(2)設(shè)置窗體的Text的屬性值為“多線程互斥(Monitor)”。(3)在原項(xiàng)目程序基礎(chǔ)上,進(jìn)行相應(yīng)的代碼調(diào)整(修改或刪除部分均以/*…*/進(jìn)行注釋)(詳細(xì)代碼見教材)6.4.3多線程互斥程序開發(fā)3.Mutex:一般用于多進(jìn)程之間的同步概述在使用方法上,Mutex與Monitor類似。但是,由于Mutex不具備Wait、Pulse和PulseAll幾種方法,因此,它不能實(shí)現(xiàn)類似Monitor的喚醒功能。另外,因?yàn)榛コ怏wMutex屬于內(nèi)核對(duì)象,進(jìn)行線程同步時(shí),線程須在用戶模式和內(nèi)核模式間切換,所以,需要的互操作轉(zhuǎn)換更耗資源,效率較低。不過Mutex有一個(gè)比較大的特點(diǎn),Mutex是跨進(jìn)程的,因此可以在同一臺(tái)機(jī)器甚至遠(yuǎn)程的機(jī)器上的多個(gè)進(jìn)程上使用同一個(gè)互斥體。用法類似于Monitor,在Mutex類中也有2個(gè)常用方法,如下表所示。方法說明WaitOne()捕獲互斥對(duì)象ReleaseMutex()釋放被捕獲的對(duì)象6.4.3多線程互斥程序開發(fā)Mutex類的基本用法也與Monitor類似,如下://對(duì)象實(shí)例化一個(gè)Mutex對(duì)象(不需聲明一個(gè)“令牌”)privateMutexmut=newMutex();…mut.WaitOne();try{//互斥段的代碼DoSomething();……}//對(duì)象非正常釋放catch(ThreadAbortException等異常){mut.ReleaseMutex();}//對(duì)象正常釋放mut.ReleaseMutex();6.4.3多線程互斥程序開發(fā)示例程序設(shè)計(jì)說明:在此,仍然設(shè)計(jì)一個(gè)chpt6-4b所示功能的示例。由于Mutex的用法類似于Monitor,所以,只需在示例chpt6-4b的基礎(chǔ)上適當(dāng)修改代碼即可?!臼纠a:chpt6-4c\ThreadMutex1】設(shè)計(jì)步驟如下:(1)復(fù)制項(xiàng)目文件夾chpt6-4b,并將其重新命名為chpt6-4c。(2)設(shè)置窗體的Text的屬性值為“多線程互斥(Mutex)”。(3)在原項(xiàng)目程序基礎(chǔ)上,進(jìn)行相應(yīng)的代碼調(diào)整(增加、修改或刪除部分均以/*…*/進(jìn)行注釋)。實(shí)際上,只需首先實(shí)例化一個(gè)Mutex對(duì)象,如:privateMutexmut=newMutex();然后,分別將原程序中的Monitor.Enter(this);代之以mut.WaitOne();,Monitor.Exit(this);代之以mut.ReleaseMutex();即可。(詳細(xì)代碼見教材)6.4.3多線程互斥程序開發(fā)Mutex有個(gè)最常見的用途:用于控制一個(gè)應(yīng)用程序只能有一個(gè)實(shí)例運(yùn)行:參見程序:SingleObject6.4.3多線程互斥程序開發(fā)4.ReaderWriterLock概述.Net提供的ReaderWriterLock定義了支持單個(gè)寫線程和多個(gè)讀線程的鎖,用于同步對(duì)資源的訪問。利用讀寫鎖,在任一特定時(shí)刻,允許多個(gè)線程同時(shí)進(jìn)行讀操作,或者允許單個(gè)線程進(jìn)行寫操作。用法ReaderWriterLock類的4個(gè)常用方法如下表所示。方法說明AcquireWriterLock(intmillisecondsTimeout)或AcquireWriterLock(TimeSpantimeout)超時(shí)值使用整數(shù)或者TimeSpane:-1表示線程將無限期等待直到獲得鎖為止,對(duì)于指定整數(shù)超時(shí)的方法,可以使用常數(shù)Infinite。0表示線程不等待獲取鎖,如果無法立即獲取鎖,方法將返回。大于0表示要等待的毫秒數(shù)。AcquireReaderLock(intmillisecondsTimeout)或AcquireReaderLock(TimeSpantimeout)(超時(shí)值用法同AcquireWriterLock方法)ReleaseWriterLock()釋放編寫鎖ReleaseReaderLock()釋放讀取鎖6.4.3多線程互斥程序開發(fā)ReaderWriterLock的基本用法如下://創(chuàng)建閱讀器和編寫器鎖privateReaderWriterLockrwl=newReaderWriterLock();…//寫操作rwl.AcquireWriterLock();try{//互斥段的代碼DoSomething();……}//寫對(duì)象非正常釋放catch(ThreadAbortException等異常){rwl.ReleaseWriterLock();}//寫對(duì)象正常釋放rwl.ReleaseWriterLock();…6.4.3多線程互斥程序開發(fā)//讀操作rwl.AcquireReaderLock();try{//互斥段的代碼DoSomething();……}//讀對(duì)象非正常釋放catch(ThreadAbortException等異常){rwl.ReleaseReaderLock();}//讀對(duì)象正常釋放rwl.ReleaseReaderLock();6.4.4多線程同步程序開發(fā)1.類比示例簡(jiǎn)析多工種協(xié)同生產(chǎn)示意圖:2.線程示例簡(jiǎn)析多線程同步:6.4.4多線程同步程序開發(fā)3.示例程序設(shè)計(jì)【示例代碼:chpt6-5\ThreadSynchronize】窗體Form1及其各控件的屬性設(shè)置
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(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ǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年深圳市福田區(qū)荔園教育集團(tuán)附屬幼兒園公開招聘短期教師備考題庫含答案詳解
- 中國(guó)電建集團(tuán)貴州工程有限公司2026屆秋季招聘150人備考題庫及完整答案詳解一套
- 2025年新疆晨玖建設(shè)工程有限責(zé)任公司市場(chǎng)化選聘工作人員備考題庫及1套完整答案詳解
- 簡(jiǎn)約企業(yè)年終工作總結(jié)匯報(bào)模板
- 中國(guó)人民人壽保險(xiǎn)股份有限公司重慶市分公司2026年度校園招聘?jìng)淇碱}庫及參考答案詳解1套
- 2025年復(fù)旦大學(xué)附屬華東醫(yī)院《老年醫(yī)學(xué)與保健》專職編輯招聘?jìng)淇碱}庫帶答案詳解
- 2025年重慶兩江新區(qū)民心佳園小學(xué)校物業(yè)項(xiàng)目經(jīng)理招聘?jìng)淇碱}庫及一套完整答案詳解
- 2025年浙江省經(jīng)濟(jì)建設(shè)投資有限公司招聘?jìng)淇碱}庫完整答案詳解
- 2025年關(guān)于公開招聘派遣至莆田市城廂區(qū)交通運(yùn)輸局非在編工作人員的備考題庫及完整答案詳解一套
- 2025年中南大學(xué)湘雅基礎(chǔ)醫(yī)學(xué)院非事業(yè)編制人員招聘?jìng)淇碱}庫及答案詳解參考
- 2025秋蘇教版(2024)小學(xué)科學(xué)二年級(jí)第一學(xué)期期末質(zhì)量檢測(cè)卷附答案
- 制鞋工人崗位培訓(xùn)
- 黑龍江省哈爾濱市2025-2026學(xué)年九年級(jí)上學(xué)期期中語文試題(含答案及解析)
- 購物中心應(yīng)急預(yù)案流程圖
- 離婚協(xié)議(2026年版本)
- 安全員c證考試真題庫及答案
- 舟山事業(yè)編考試題及答案
- 2025年中小學(xué)生趣味百科知識(shí)競(jìng)賽題庫及答案
- 2025年低空經(jīng)濟(jì)行業(yè)碳排放與環(huán)境影響報(bào)告
- 銀行理財(cái)經(jīng)理先進(jìn)工作事跡材料
- git內(nèi)部培訓(xùn)課件
評(píng)論
0/150
提交評(píng)論