第2章進程管理-3_第1頁
第2章進程管理-3_第2頁
第2章進程管理-3_第3頁
第2章進程管理-3_第4頁
第2章進程管理-3_第5頁
已閱讀5頁,還剩72頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

互斥與同步解決方法之三:

信號量方法軟件方法和硬件方法都存在"忙等"問題,浪費了處理機時間。而信號量方法能夠?qū)崿F(xiàn)進程的互斥和同步,而不必"忙等"。實例交通信號燈:紅燈停,綠燈行整型信號量最初由Dijkstra把整型信號量定義為一個用于表示資源數(shù)目的整型量S,它與一般整型量不同,除初始化外,僅能通過兩個標準的原子操作(AtomicOperation)wait(S)和signal(S)來訪問。很長時間以來,這兩個操作一直被分別稱為P、V操作。Wait(S)和signal(S)操作可描述為:

wait(S):while S<=0dono-op;

S:=S-1;

signal(S): S:=S+1;記錄型信號量的基本原理兩個或多個進程可以通過傳遞信號進行合作,可以迫使進程在某個位置暫時停止執(zhí)行(阻塞等待),直到它收到一個可以"向前推進"的信號為止(被喚醒)。相應(yīng)地,記錄型信號量應(yīng)該包括兩個域:一個整型域,表示資源的數(shù)目,另外一個域為隊列,其元素為等待該信號量而阻塞的進程。記錄型信號量的定義typesemaphore=record

value:integer;

L:listofprocess;

end相應(yīng)地,wait(S)和signal(S)操作可描述為:procedurewait(S)

varS:semaphore;

begin

S.value:=S.value-1;

ifS.value<0thenblock(S.L);

endproceduresignal(S)

varS:semaphore;

begin

S.value:=S.value+1;

ifS.value<=0thenwakeup(S.L);

endwait和signal的應(yīng)用進程進入臨界區(qū)之前,首先執(zhí)行wait(S)原語,如果S.value<0則進程調(diào)用阻塞原語,將自己阻塞,并插入到S.L隊列中等待。注意,阻塞進程不會占用處理機時間,不是忙等.直到某個從臨界區(qū)退出的進程執(zhí)行signal(S)原語,喚醒它。一旦其它某個進程執(zhí)行了原語signal(S),S.value值加1,如果S.value<=0,即阻塞隊列中還有被阻塞進程,則調(diào)用喚醒原語,把S.L中的第一個進程的狀態(tài)修改為就緒狀態(tài),并插入到就緒隊列中,準備執(zhí)行臨界區(qū)代碼.信號量類型信號量分為:互斥信號量和資源信號量。互斥信號量用于申請或釋放資源的使用權(quán),常初始化為1。資源信號量用于申請或歸還資源,可以初始化為大于1的正整數(shù),表示系統(tǒng)中某類資源的可用個數(shù)。wait操作用于申請資源(或使用權(quán)),進程執(zhí)行wait原語時,可能會阻塞自己。signal操作用于釋放資源(或歸還資源使用權(quán)),進城執(zhí)行signal原語時,有責(zé)任喚醒一個阻塞進程。信號量類型的物理意義S.value>0表示還可執(zhí)行wait(S)而不會阻塞的進程數(shù)(可用資源數(shù))。每執(zhí)行一次wait(S)操作,就意味著請求分配一個單位的資源。當(dāng)S.value<=0時,表示無資源可用,因此請求該資源的進程被阻塞。此時S.value絕對值等于該信號量阻塞隊列中的等待進程數(shù)。執(zhí)行一次signal操作,就意味著釋放一個單位的資源。若S.value<0,表示S.L隊列中還有被阻塞的進程,需要喚醒該隊列中的第一個進程,將它轉(zhuǎn)移到就緒隊列中。S.value的取值范圍當(dāng)僅有兩個并發(fā)進程共享臨界資源時,互斥信號量僅能取之0,1,-1,其中,

-S.value=1,表示無進程進入臨界區(qū)-S.value=0,表示已經(jīng)有一個進程進入臨界區(qū)-S.value=-1,表示已有一個進程正在等待進入臨界區(qū)當(dāng)用S來實現(xiàn)n個進程的互斥時,S.value的取值范圍為1-(n-1)AND型信號量上述的進程互斥問題,是針對各進程之間只共享一個臨界資源而言的。在有些應(yīng)用場合,是一個進程需要先獲得兩個或更多的共享資源后方能執(zhí)行其任務(wù)。假定現(xiàn)有兩個進程A和B,他們都要求訪問共享數(shù)據(jù)D和E。當(dāng)然,共享數(shù)據(jù)都應(yīng)作為臨界資源。為此,可為這兩個數(shù)據(jù)分別設(shè)置用于互斥的信號量Dmutex和Emutex,并令它們的初值都是1。相應(yīng)地,在兩個進程中都要包含兩個對Dmutex和Emutex的操作,即processA:

processB:wait(Dmutex);wait(Emutex);wait(Emutex);wait(Dmutex);AND型信號量若進程A和B按下述次序交替執(zhí)行wait操作:

processA:wait(Dmutex);于是Dmutex=0

processB:wait(Emutex);于是Emutex=0

processA:wait(Emutex);于是Emutex=-1A阻塞

processB:wait(Dmutex);于是Dmutex=-1B阻塞最后,進程A和B處于僵持狀態(tài)。在無外力作用下,兩者都將無法從僵持狀態(tài)中解脫出來。我們稱此時的進程A和B已進入死鎖狀態(tài)。顯然,當(dāng)進程同時要求的共享資源愈多時,發(fā)生進程死鎖的可能性也就愈大。AND型信號量

AND同步機制的基本思想是:將進程在整個運行過程中需要的所有資源,一次性全部地分配給進程,待進程使用完后再一起釋放?!窗阉埱蟮馁Y源全部分配到進程,要么一個也不分配。方法:在wait操作中,增加了一個“AND”條件,故稱為AND同步,或稱為同時wait操作,即Swait(Simultaneouswait)定義如下:Swait(S1,S2,…,Sn)

ifSi>=1and…andSn>=1then

fori:=1tondo

Si:=Si-1;

endfor

else

placetheprocessinthewaitingqueueassociatedwiththefirstSifoundwithSi<1,andsettheprogramcountofthisprocesstothebeginningofSwaitoperation

endifSsignal(S1,S2,…,Sn)fori:=1tondo

Si:=Si+1;RemovealltheprocesswaitinginthequeueassociatedwithSiintothereadyqueue.endfor;信號量集在記錄型信號量機制中,wait(S)和signal(S)僅能對信號量進行加1和減1操作,意味著每次只能獲得和釋放一個單位的臨界資源。而當(dāng)一次需要N個某類的臨界資源時,便要進行N次wait(S)操作,顯然是低效的。此外,在有些情況下,當(dāng)資源量低于某一下限時,便不予分配。因而,在每次分配前,都必須測試該資源量的數(shù)量,看其是否大于其下限值。基于以上兩點,可以對AND信號機制加以擴充,形成一般的“信號量集”。Swait和Ssignal操作描述如下:Swait(S1,t1,d1,…,Sn,tn,dn)

ifSi>=t1and…andSn>=dnthen

fori:=1tondo

Si:=Si-di;

endfor

else

placetheprocessinthewaitingqueueassociatedwiththefirstSifoundwithSi<ti,andsettheprogramcountofthisprocesstothebeginningofSwaitoperation

endifSsignal(S1,d1,…,Sn,dn)fori:=1tondo

Si:=Si+di;RemovealltheprocesswaitinginthequeueassociatedwithSiintothereadyqueue.endfor;信號量集幾種特殊的情況(1)Swait(S,d,d):此時在信號量集中只有一個信號量S,但允許它每次申請d個資源,當(dāng)現(xiàn)有資源少于d時,不予分配;(2)Swait(S,1,1):此時信號量集蛻化為一般的記錄型信號量(S>1)或互斥型信號量(S=1);(3)Swait(S,1,0):這是一種特殊且很有用的信號量操作。當(dāng)S>=1時,允許多個進程進入特定區(qū);當(dāng)S變?yōu)?時,將阻止任何進程進入特定區(qū)。換言之,它相當(dāng)于一個可控開關(guān)。使用信號量解決問題的關(guān)鍵步驟:1)信號量的設(shè)置;2)給信號量賦初值(常用的互斥和同步信號量值的大小);3)P、V操作安排的位置。注意:1)若有多個信號量,信號量的P操作的順序不能任意,通常先對資源信號量執(zhí)行P操作,然后對互斥信號量進行P操作,而V操作的順序可以任意;2)互斥信號量其P和V操作通常在同一個進程內(nèi);而資源信號量的P和V操作通常分布在不同的進程內(nèi)。利用信號量實現(xiàn)進程互斥Varmutex:semaphore:=1;

begin

parbegin

process1:process2:parendprocess1、2:begin

repeat

wait(mutex);

criticalsection

signal(mutex);

remaindersection

untilfalse;

end

利用信號量實現(xiàn)進程的同步P

Q

Buffer1假設(shè)有一個輸入進程P和一個計算進程Q,共享一個緩沖區(qū),輸入進程輸入數(shù)據(jù),計算進程處理數(shù)據(jù),如何實現(xiàn)二者的同步。Varempty,full:semaphore:=1,0;P:wait(empty);Q:wait(full);

輸入數(shù)據(jù);處理數(shù)據(jù);

signal(full);

signal(empty);利用信號量實現(xiàn)進程的同步(擴展1)假設(shè)有一個輸入進程P可以接收兩種數(shù)據(jù):奇數(shù)和偶數(shù),計算進程Q1負責(zé)處理奇數(shù)數(shù)據(jù),計算進程Q2負責(zé)處理偶數(shù)數(shù)據(jù)。Varempty,full1,full2:semaphore:=1,0,0;P:wait(empty);Q1:wait(full1);Q2:wait(full2);

輸入數(shù)據(jù);處理奇數(shù);處理偶數(shù);

if(是奇數(shù))

signal(empty);

signal(empty);

signal(full1);elsesignal(full2);Buffer1PQ1Q2利用信號量實現(xiàn)進程的同步(擴展2)假設(shè)有有兩個輸入進程P1和P2分別接收奇數(shù)和偶數(shù),計算進程Q1和Q2分別負責(zé)處理奇數(shù)和偶數(shù)數(shù)據(jù)。Varempty,full1,full2:semaphore:=1,0,0;P1:wait(empty);P2:wait(empty);Q1:wait(full1);Q2:wait(full2);

輸入奇數(shù);輸入偶數(shù);處理奇數(shù)處理偶數(shù)

signal(full1);

signal(full2);signal(empty);

signal(empty);Buffer1P1Q1Q2P2利用信號量實現(xiàn)進程的同步(擴展3)Buffer1假設(shè)進程P負責(zé)數(shù)據(jù)的輸入,進程K負責(zé)數(shù)據(jù)的加工,進程Q負責(zé)數(shù)據(jù)的打印。PQKVarempty,full1,full2:semaphore:=1,0,0;P:wait(empty);K:wait(full1);Q:wait(full2);

輸入數(shù)據(jù);取數(shù)據(jù)打印數(shù)據(jù);

signal(full1);數(shù)據(jù)加工;

signal(empty);

signal(full2);

利用信號量實現(xiàn)進程的同步(練習(xí))吃水果問題:假設(shè)桌上有一個空盤子,一次僅允許放一個水果,利用信號量的P,V操作解決下列同步問題:1)父親負責(zé)放水果,兒子負責(zé)吃水果;2)父親負責(zé)水果(蘋果或桔子),兒子吃蘋果,女兒吃桔子;3)父親負責(zé)放蘋果,母親負責(zé)放桔子,兒子吃蘋果,女兒吃桔子;4)父親負責(zé)放蘋果,母親負責(zé)削皮,兒子負責(zé)吃蘋果。思考思考:有三個進程:進程get:從輸入設(shè)備上不斷讀數(shù)據(jù),并存入緩沖區(qū)Buffer1;進程copy:不斷將緩沖區(qū)Buffer1的內(nèi)容復(fù)制到緩沖區(qū)Buffer2;進程put:則不斷將Buffer2的內(nèi)容在打印機上輸出,get

copy

put

Buffer1Buffer23個進程的協(xié)同工作

為了使三個進程并發(fā)工作以大大加快執(zhí)行速度,又保證打印結(jié)果和輸入結(jié)果一致,三個進程之間必須協(xié)調(diào)工作。★設(shè)四個信號量S1、S2、S3、S4,令:

S1:初值為1,表示緩沖區(qū)Buffer1空閑的單元數(shù);

S2:初值為0,表示緩沖區(qū)Buffer1數(shù)據(jù)的個數(shù);

S3:初值為1,表示緩沖區(qū)Buffer2空閑的單元數(shù);

S4:初值為0,表示緩沖區(qū)Buffer2中數(shù)據(jù)個數(shù)。進程get

進程copy

進程putP(S1);P(S2);P(S4);從輸入設(shè)備向P(S3);將緩沖區(qū)Buffer2緩沖區(qū)Buffer1將Buffer1內(nèi)容內(nèi)容在打印機上輸出;中寫數(shù)據(jù);復(fù)制到Buffer2V(S3);V(S2);V(S1);

V(S4);………………3個進程之間的同步信號量的應(yīng)用

-實現(xiàn)前趨關(guān)系方法:若圖中存在結(jié)點S1指向結(jié)點S2的有向邊,表示進程P1中的程序段S1應(yīng)該先執(zhí)行,而進程P2中的程序段S2后執(zhí)行。設(shè)置一個信號量s,初值為0,將signal(s)放在S1后面,而在S2前面先執(zhí)行wait(s)。進程P1的語句序列為:S1;signal(s)進程P2的語句序列為:wait(s);S2

S1S2s信號量的應(yīng)用

-實現(xiàn)前趨關(guān)系要點1)信號量的個數(shù)=有向邊的個數(shù)2)每一個進程對應(yīng)的語句結(jié)點的入邊和出邊分別處理:對于入邊的信號量執(zhí)行P操作,并放置在該語句的前面;對于出邊的信號量執(zhí)行V操作,并放置在該語句的后面;Vara,b,c,d,e,f,g:semaphore:=0,0,0,0,0,0,0;

begin

parbegin

beginS1;

signal(a);

signal(b);

end;

beginwait(a);

S2;

signal(c);

signal(d);

end;

beginwait(b);

S3;

signal(e);

end;

beginwait(c);

S4;

signal(f);

end;

beginwait(d);

S5;

signal(g);

end;

beginwait(e);

wait(f);

wait(g);

S6;

end;

parend

end信號量的使用要點

信號量的物理含義:-S>0表示有S個資源可用-S<0則|S|表示S等待隊列中的進程個數(shù)必須置一次且只能置一次初值初值不能為負數(shù)只能執(zhí)行wait、signal操作必須成對使用wait和signal原語:-遺漏P原語則不能保證互斥訪問-遺漏V原語則不能在使用臨界資源之后將其釋放(給其他等待的進程)-P、V原語不能次序錯誤、重復(fù)或遺漏2.4經(jīng)典進程的同步問題生產(chǎn)者-消費者問題生產(chǎn)者與消費者是一個廣義的概念,可以代表一類具有相同屬性的進程。生產(chǎn)者和消費者進程共享一個大小固定的緩沖區(qū),其中,一個或多個生產(chǎn)者生產(chǎn)數(shù)據(jù),并將生產(chǎn)的數(shù)據(jù)存入緩沖區(qū),并有一個消費者從緩沖區(qū)中取數(shù)據(jù)。假設(shè)緩沖區(qū)的大小為n(存儲單元的個數(shù)),它可以被生產(chǎn)者和消費者循環(huán)使用。分別設(shè)置兩個指針in,out,指向生產(chǎn)者將存放數(shù)據(jù)的存儲單元和消費者將取數(shù)據(jù)的存儲單元。生產(chǎn)者/消費者必須互斥生產(chǎn)者和消費者可能同時進入緩沖區(qū),甚至可能同時讀/寫一個存儲單元,將導(dǎo)致執(zhí)行結(jié)果的不確定性。這顯然是不允許的,必須使生產(chǎn)者和消費者互斥進入緩沖區(qū),即,某時刻只允許一個進程(生產(chǎn)者或消費者)訪問緩沖區(qū),生產(chǎn)者互斥消費者和其他任何生產(chǎn)者。生產(chǎn)者/消費者必須同步生產(chǎn)者不能向滿緩沖區(qū)寫數(shù)據(jù),消費者也不能在空緩沖區(qū)中取數(shù)據(jù),即生產(chǎn)者和消費者必須同步。Varmutex:semaphore(:=1);/*互斥信號量*/

empty:semaphore(:=n);/*資源信號量,空存儲單元*/

full:semaphore(:=0);/*資源信號量,數(shù)據(jù)單元*/

buffer:array[0,…,n-1]ofitem;in,out:integer:=0,0;procedureproducer;procedureconsumer;beginbeginrepeatrepeatproduceranitemnexttp;wait(full);wait(empty);wait(mutex);wait(mutex);nextc:=buffer(out);buffer(in):=nextp;out=(out+1)modn;in=(in+1)modn;signal(mutex);signal(mutex);signal(empty);signal(full);consumertheiteminnextc;untilfalse;untilfalse;endendbeginparbeginproducer;consumer;parendend注意進程應(yīng)該先申請資源信號量,再申請互斥信號量,順序不能顛倒,否則可能引起進程的死鎖;對任何信號量的wait與signal操作必須配對;同一信號量的wait與signal可以在不同的進程中;讀者-寫者問題該問題描述為多個進程訪問一個共享數(shù)據(jù)區(qū),如數(shù)據(jù)庫,文件,內(nèi)存區(qū)及一組寄存器等的數(shù)據(jù)問題建立一個通用模型,其中若干個讀進程只能讀數(shù)據(jù),若干寫進程只能寫數(shù)據(jù)。例如,一個聯(lián)網(wǎng)售票系統(tǒng),數(shù)據(jù)的查詢和更新非常頻繁,不可避免會出現(xiàn)多個進程試圖查詢或修改其中某一條數(shù)據(jù)的情形,多個進程同時讀一條記錄是可以的,但如果一個進程正在更新數(shù)據(jù)庫的某條記錄,則所有其他進程不能訪問(讀或?qū)懀┰撚涗洠駝t可能將同一個座位銷售多次。讀者-寫者進程滿足的條件允許多個讀者進程同時讀數(shù)據(jù);不允許多個寫者進程同時寫數(shù)據(jù),即只能互斥寫數(shù)據(jù);若有寫者進程正在寫數(shù)據(jù),則不允許讀者進程讀數(shù)據(jù)。讀者優(yōu)先當(dāng)一個讀者正在讀數(shù)據(jù)時,另一個讀者也需要讀數(shù)據(jù),應(yīng)允許第二個讀者進入,同理第三個及隨后更多的讀者都被允許進入;現(xiàn)在假設(shè)一個寫者到來,由于寫操作是排他的,所以他不能訪問數(shù)據(jù),需要阻塞等待。如果一直都有新的讀者陸續(xù)到來,寫者的寫操作被嚴重推遲;該方法稱為“讀者優(yōu)先”,即,一旦讀者正在讀數(shù)據(jù),允許多個讀者同時讀數(shù)據(jù),只有當(dāng)全部讀者退出,才允許寫者進入寫數(shù)據(jù)。Varrmutex,wmutex:semaphore:=1,1;/*互斥信號量*/

Readcount:integer:=0;procedurereader;procedurewriter;

beginbegin

repeatrepeat

wait(rmutex);waite(wmutex);

ifreadcount=0thenwait(wmutex);寫數(shù)據(jù);

Readcount:=Readcount+1;signal(wmutex);

signal(rmutex);untilfalse;讀數(shù)據(jù);end

wait(rmutex);Readcount:=Readcount-1;

ifReadcount=0thensignal(wmutex);

signal(rmutex);

untilfalse;endbeginparbeginreader;writer;parendend信號量集機制這里增加一個限制,即最多只允許RN個讀者同時讀。為此,又引入一個信號量L,并賦予其初值為RN,通過執(zhí)行Swait(L,1,1)操作,來控制讀者的數(shù)目。每當(dāng)有一個讀者進入時,執(zhí)行Swait(L,1,1),使L的值減1,當(dāng)RN個讀者進入讀后,L便減為0,當(dāng)?shù)赗N+1個讀者進入讀時,必然會因Swait(L,1,1)操作失敗而阻塞。VarL,mx=RN,1;/*互斥信號量*/procedurereader;procedurewriter;

beginbegin

repeatrepeatSwait(L,1,1);Swaite(mx,1,1;L,RN,0);Swait(mx,1,0);寫數(shù)據(jù)讀數(shù)據(jù);Ssignal(mx,1);Ssignal(L,1);untilfalse;

untilfalse;endendbeginparbeginreader;writer;parendend注意Swait(mx,1,0)起到開關(guān)作用,只要無寫進程進入寫,任何讀進程都可以讀,否則,任何讀進程都無發(fā)進入讀;Swait(mx,1,1;L,RN,0)表示僅當(dāng)無寫進程進入寫,又無讀進程在讀,寫進程才能進入寫。寫者優(yōu)先為了防止“讀者優(yōu)先”可能導(dǎo)致寫者饑餓,可以考慮寫者優(yōu)先;即,當(dāng)共享數(shù)據(jù)區(qū)被讀者占用時,后續(xù)緊鄰到達的讀者可以繼續(xù)進入,若這時有一個寫者到來且阻塞等待,則寫者后面到達的若干讀者全部阻塞等待。換句話,只要有一個寫者申請寫數(shù)據(jù),則不允許新的讀者進入讀數(shù)據(jù),這樣,寫者只需等待優(yōu)先于它到來的讀者完成其獨數(shù)據(jù)任務(wù),而不用等待起后到來的讀者。這種方案解決了寫者饑餓問題,但降低了并發(fā)程度,使系統(tǒng)的性能較差。哲學(xué)家進餐問題問題描述:(由Dijkstra首先提出并解決)5個哲學(xué)家圍繞一張圓桌而坐,桌子上放著5支筷子,每兩個哲學(xué)家之間放一支;每個哲學(xué)家的行為是思考,感到饑餓,然后吃通心粉進餐時需要同時拿起他左邊和右邊的兩支筷子,并且每個人只能直接從自己的左邊或右邊去取筷子。吃完思考時則同時將兩支筷子放回原處。ABCDE12345

Varchopstick:array[0,…,4]ofsemaphore;所有信號量均被初始化為1,第i位哲學(xué)家的活動可描述為:

repeat

wait(chopstick[i]);

wait(chopstick[(i+1)mod5]);

eat;

signal(chopstick[i]);

signal(chopstick[(i+1)mod5]);

think;

untilfalse;………資源競爭導(dǎo)致僵持的解決方法:

(1)至多只允許有四位哲學(xué)家同時去拿左邊的筷子,最終能保證至少有一位哲學(xué)家能夠進餐,并在用畢時能釋放出他用過的兩只筷子,從而使更多的哲學(xué)家能夠進餐。

(2)僅當(dāng)哲學(xué)家的左、右兩只筷子均可用時,才允許他拿起筷子進餐。

(3)規(guī)定奇數(shù)號哲學(xué)家先拿他左邊的筷子,然后再去拿右邊的筷子,而偶數(shù)號哲學(xué)家則相反。按此規(guī)定,將是1、2號哲學(xué)家競爭1號筷子;3、4號哲學(xué)家競爭3號筷子。即五位哲學(xué)家都先競爭奇數(shù)號筷子,獲得后,再去競爭偶數(shù)號筷子,最后總會有一位哲學(xué)家能獲得兩只筷子而進餐?!締栴}1】

要求寫一個函數(shù)或方法,能顯示出一個int類型數(shù)組的元素個數(shù)及元素的內(nèi)容.

【解決方法1】

調(diào)用一個顯示數(shù)組元素個數(shù)和元素內(nèi)容的函數(shù)時,將數(shù)組與說明此數(shù)組元素個數(shù)一并作為參數(shù)傳遞過去。

#include<iostream.h>voidshowArray(intArray[],intLen){inti;for(i=0;i<Len;i++)/*顯示數(shù)組元素的內(nèi)容*/cout<<Array[i]<<"";}voidmain(){intArray[10];/*這就是要顯示的數(shù)組,設(shè)置了10個元素*/intLen=10;/*用一個int類型變量記錄此數(shù)組的元素個數(shù)*/inti;cout<<"請輸入10個整數(shù):";for(i=0;i<Len;i++)/*初始化數(shù)組*/cin>>Array[i];showArray(Array,Len);/*調(diào)用顯示數(shù)組元素個數(shù)及內(nèi)容的函數(shù)*/}【問題1】

要求寫一個函數(shù)或方法,能顯示出一個int類型數(shù)組的元素個數(shù)及元素的內(nèi)容.

【解決方法2】

將數(shù)組和描述它元素個數(shù)的數(shù)值通過結(jié)構(gòu)體放在了一起.structintArray/*定義一個intArray結(jié)構(gòu)體*/{intLen;/*這是本結(jié)構(gòu)體表示的數(shù)組的元素個數(shù)*/inta[10];};#include"iostream.h"structintArray/*定義一個intArray結(jié)構(gòu)體*/{intLen;/*這是本結(jié)構(gòu)體表示的數(shù)組的元素個數(shù)*/inta[10];};voidshowArray(structintArrayp){inti;for(i=0;i<p.Len;i++)cout<<p.a[i]<<"";}voidmain(){structintArrayp;inti;

p.Len=10;/*為這個結(jié)構(gòu)體的元素個數(shù)準確賦值*/ cout<<"請輸入10個整數(shù):";

for(i=0;i<p.Len;i++)cin>>p.a[i];showArray(p);}這樣傳遞給函數(shù)showArray()時,就只是一個參數(shù)。

但這個方案比第一個方案多增加了一結(jié)構(gòu)體的概念,而且結(jié)構(gòu)體中的數(shù)組int

a[10],它的元素個數(shù)也是固定的,p.Len的值只能是10,當(dāng)p.Len為其他的值時就會出錯。

注意:使用結(jié)構(gòu)體,代碼里就已經(jīng)有了一點面向?qū)ο蟮幕靖拍盍?,只是并不十分清晰?!締栴}1】

要求寫一個函數(shù)或方法,能顯示出一個int類型數(shù)組的元素個數(shù)及元素的內(nèi)容.

【解決方法3】

使用動態(tài)分配內(nèi)存的方法,使數(shù)組的元素個數(shù)隨意分配.#include"iostream.h"structintArray{intLen;

int*a;};voidshowArray(structintArrayp){inti;for(i=0;i<p.Len;i++)cout<<p.a[i]<<"";}voidmain(){structintArrayp;inti;p.Len=5;/*隨意給這個數(shù)組分配n個元素*/

p.a=newint[p.Len];/*在內(nèi)存中開辟了一個n個int類型的內(nèi)存塊,并返回其地址*/for(i=0;i<p.Len;i++)cin>>p.a[i];showArray(p);

delete[]p.a;/*不要忘了釋放開辟的內(nèi)存空間*/ }通過動態(tài)分配的方法,實現(xiàn)了數(shù)組元素個數(shù)的任意分配,并且其數(shù)組個數(shù)的屬性Len如實地表達出了數(shù)組的個數(shù),而不需要我們操心.該解決方法要比前兩個解決方法都要進步,但是做的工作也多了一點,這里就涉及到了一個動態(tài)分配的概念,而且一定要使用delete這個函數(shù)來釋放掉動態(tài)分配的內(nèi)存,否則會造成內(nèi)存泄露,顯然,多增加了一些代碼編寫的風(fēng)險.

此問題如何方便有效地得到解決的?

其解決問題的思路,與這個方法是一樣的,就是使數(shù)組被封裝進一個類中,使之成為一個對象來考慮.一個類就是一個擴展的struct。除了定義數(shù)據(jù)成員,你還可以為其添加成員函數(shù)。

注意:

通過對問題1的演示與一步一步的改善方法,我們已經(jīng)初步轉(zhuǎn)向了面向?qū)ο蟮乃季S方式。

【問題1】

要求寫一個函數(shù)或方法,能顯示出一個int類型數(shù)組的元素個數(shù)及元素的內(nèi)容.

【解決方法4】

使用C++的面向?qū)ο蠓椒ā?/p>

#include<iostream.h>classintArray{private: intLen;int*a;public:intArray(intsize)//進行內(nèi)存分配并初始化賦值{Len=size;a=newint[Len];//開辟內(nèi)存inti; cout<<"請輸入"<<Len<<"個整數(shù):";for(i=0;i<Len;i++)cin>>a[i];}voidshowArray(){inti; cout<<"數(shù)組元素有:";for(i=0;i<Len;i++)cout<<a[i]<<"";}~intArray(){delete[]a;//釋放內(nèi)存}};voidmain(){/*創(chuàng)建intArray類型的對象實例p,并指定其數(shù)組元素為5個*/

intArrayp(5);/*直接調(diào)用此實例的方法來顯示其內(nèi)容,這里,我們不給這個函數(shù)傳遞參數(shù),因為這個函數(shù)要顯示的,是它自身對象的內(nèi)容*/

p.showArray();}

對于一個封裝好的類,我們只是將此類intArray實例化并初始化,然后調(diào)用它的顯示方法就完成了上面我們所做的很多工作.只要設(shè)計并封裝好類,對于類的內(nèi)部細節(jié)我們做好后就不必去關(guān)心,事實上,如果你把你的類提供給另外一個人,他只要寫2行代碼就能解決這個問題.而像上面的那3個解決方法,你可以數(shù)一下,在別人使用你提供的函數(shù)后,他究竟要寫多少行代碼,要關(guān)心多少個細節(jié)問題才能不出錯?

同步操作分散:信號量機制中,同步操作分散在各個進程中,使用不當(dāng)就可能導(dǎo)致各進程死鎖(如P、V操作的次序錯誤、重復(fù)或遺漏)易讀性差:要了解對于一組共享變量及信號量的操作是否正確,必須通讀整個系統(tǒng)或者并發(fā)程序用戶負擔(dān):由用戶自己編寫控制代碼,加重用戶負擔(dān)互斥與同步解決方法之四:

管程方法管程的引入1973年,Hoare和Hanson所提出;其基本思想是把信號量及其操作原語封裝在一個對象內(nèi)部即:將共享變量以及對共享變量能夠進行的所有操作集中在一個模塊中管程的定義:管程是關(guān)于共享資源的數(shù)據(jù)結(jié)構(gòu)及一組針對該資源的操作過程所構(gòu)成的軟件模塊。管程的組成由上述的定義可知,管程由四部分組成:①管程的名稱;②局部于管程內(nèi)部的共享數(shù)據(jù)結(jié)構(gòu)說明;③對該數(shù)據(jù)結(jié)構(gòu)進行操作的一組過程;④對局部于管程內(nèi)部的共享數(shù)據(jù)設(shè)置初始值的語句。type<管程名>=MONITOR;<管程變量說明>;procedure<過程名>(<形式參數(shù)表>);begin

<過程體>end;procedure<過程名>(<形式參數(shù)表>);begin

<過程體>end;begin<

溫馨提示

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

評論

0/150

提交評論