清華大學(xué)操作系統(tǒng)向勇老師的講義市公開課金獎(jiǎng)市賽課一等獎(jiǎng)?wù)n件_第1頁
清華大學(xué)操作系統(tǒng)向勇老師的講義市公開課金獎(jiǎng)市賽課一等獎(jiǎng)?wù)n件_第2頁
清華大學(xué)操作系統(tǒng)向勇老師的講義市公開課金獎(jiǎng)市賽課一等獎(jiǎng)?wù)n件_第3頁
清華大學(xué)操作系統(tǒng)向勇老師的講義市公開課金獎(jiǎng)市賽課一等獎(jiǎng)?wù)n件_第4頁
清華大學(xué)操作系統(tǒng)向勇老師的講義市公開課金獎(jiǎng)市賽課一等獎(jiǎng)?wù)n件_第5頁
已閱讀5頁,還剩92頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第四章進(jìn)程管理4.1進(jìn)程(PROCESS)4.2進(jìn)程控制4.3線程(THREAD)4.4進(jìn)程互斥和同時(shí)4.5進(jìn)程間通信(IPC,INTER-PROCESSCOMMUNICATION)4.6死鎖問題(DEADLOCK)4.7進(jìn)程其它方面舉例為了描述程序在并發(fā)執(zhí)行時(shí)對(duì)系統(tǒng)資源共享,我們需要一個(gè)描述程序執(zhí)行時(shí)動(dòng)態(tài)特征概念,這就是進(jìn)程。在本章中,我們將討論進(jìn)程概念、進(jìn)程控制和進(jìn)程間關(guān)系。第1頁4.1進(jìn)程(PROCESS)4.1.1程序次序執(zhí)行和并發(fā)執(zhí)行4.1.2進(jìn)程定義和描述4.1.3進(jìn)程狀態(tài)轉(zhuǎn)換4.1.4操作系統(tǒng)代碼執(zhí)行返回第2頁4.1.1程序次序執(zhí)行和并發(fā)執(zhí)行程序執(zhí)行有兩種方式:次序執(zhí)行和并發(fā)執(zhí)行。次序執(zhí)行是單道批處理系統(tǒng)執(zhí)行方式,也用于簡(jiǎn)單單片機(jī)系統(tǒng);現(xiàn)在操作系統(tǒng)多為并發(fā)執(zhí)行,含有許多新特征。引入并發(fā)執(zhí)行目標(biāo)是為了提升資源利用率并適應(yīng)多任務(wù)處理要求。第3頁次序執(zhí)行特征次序性:按照程序結(jié)構(gòu)所指定次序(可能有分支或循環(huán))封閉性:獨(dú)占全部資源,計(jì)算機(jī)狀態(tài)只因?yàn)樵摮绦蚩刂七壿嬎鶝Q定可再現(xiàn)性:初始條件相同則結(jié)果相同。如:可經(jīng)過空指令控制時(shí)間關(guān)系。并發(fā)執(zhí)行特征間斷(異步)性:"走走停停",一個(gè)程序可能走到中途停下來,失去原有時(shí)序關(guān)系;失去封閉性:共享資源,受其它程序控制邏輯影響。如:一個(gè)程序?qū)懙酱娣牌髦袛?shù)據(jù)可能被另一個(gè)程序修改,失去原有不變特征。失去可再現(xiàn)性:失去封閉性->失去可再現(xiàn)性;外界環(huán)境在程序兩次執(zhí)行期間發(fā)生改變,失去原有可重復(fù)特征。第4頁并發(fā)執(zhí)行條件:到達(dá)封閉性和可再現(xiàn)性程序P(i)針對(duì)共享變量讀集和寫集R(i)和W(i)條件:任意兩個(gè)程序P(i)和P(j),有:R(i)W(j)=;W(i)R(j)=;W(i)W(j)=;并發(fā)執(zhí)行失去封閉性原因是共享資源影響,去掉這種影響就行了。1966年,由Bernstein給出并發(fā)執(zhí)行條件。(這里沒有考慮執(zhí)行速度影響。)前兩條確保一個(gè)程序兩次讀之間數(shù)據(jù)不改變;最終一條確保寫結(jié)果不丟掉?,F(xiàn)在問題是這個(gè)條件不好檢驗(yàn)。第5頁4.1.2進(jìn)程定義和描述它對(duì)應(yīng)虛擬處理機(jī)、虛擬存放器和虛擬外設(shè)等資源分配和回收;引入多進(jìn)程,提升了對(duì)硬件資源利用率,但又帶來額外空間和時(shí)間開銷,增加了OS復(fù)雜性;1.進(jìn)程定義一個(gè)含有一定獨(dú)立功效程序在一個(gè)數(shù)據(jù)集合上一次動(dòng)態(tài)執(zhí)行過程。第6頁進(jìn)程與程序關(guān)系類比這時(shí)小兒子哭著跑進(jìn)來,說手被蜜蜂蟄了。教授只好把蛋糕先放在一邊。他在食譜上做了個(gè)標(biāo)識(shí),把狀態(tài)信息統(tǒng)計(jì)了起來。然后又去找了一本醫(yī)療手冊(cè),查到了相關(guān)內(nèi)容,按照上面指令一步步地執(zhí)行。當(dāng)傷口處理完之后,又回到廚房繼續(xù)做蛋糕。有一個(gè)計(jì)算機(jī)科學(xué)家,想親手給女兒做一個(gè)生日蛋糕。所以他就找了一本相關(guān)做蛋糕食譜,買了一些原料,面粉、雞蛋、糖、香料等,然后邊看邊學(xué)邊做。食譜=程序;科學(xué)家=CPU;原料=數(shù)據(jù);做蛋糕=進(jìn)程;CPU從一個(gè)進(jìn)程(做蛋糕)切換到另一個(gè)進(jìn)程(醫(yī)療救護(hù))。第7頁2.進(jìn)程特征動(dòng)態(tài)性:進(jìn)程含有動(dòng)態(tài)地址空間(數(shù)量和內(nèi)容),地址空間上包含:代碼(指令執(zhí)行和CPU狀態(tài)改變)數(shù)據(jù)(變量生成和賦值)系統(tǒng)控制信息(進(jìn)程控制塊生成和刪除)獨(dú)立性:各進(jìn)程地址空間相互獨(dú)立,除非采取進(jìn)程間通信伎倆;并發(fā)性、異步性:"虛擬"結(jié)構(gòu)化:代碼段、數(shù)據(jù)段和關(guān)鍵段(在地址空間中);程序文件中通常也劃分了代碼段和數(shù)據(jù)段,而關(guān)鍵段通常就是OS關(guān)鍵(由各個(gè)進(jìn)程共享,包含各進(jìn)程PCB)第8頁四個(gè)進(jìn)程在并發(fā)地運(yùn)行第9頁3.進(jìn)程與程序區(qū)分進(jìn)程是動(dòng)態(tài),程序是靜態(tài):程序是有序代碼集合;進(jìn)程是程序執(zhí)行。通常進(jìn)程不可在計(jì)算機(jī)之間遷移;而程序通常對(duì)應(yīng)著文件、靜態(tài)和能夠復(fù)制。進(jìn)程是暫時(shí),程序永久:進(jìn)程是一個(gè)狀態(tài)改變過程,程序可長(zhǎng)久保留。進(jìn)程與程序組成不一樣:進(jìn)程組成包含程序、數(shù)據(jù)和進(jìn)程控制塊(即進(jìn)程狀態(tài)信息)。進(jìn)程與程序?qū)?yīng)關(guān)系:經(jīng)過屢次執(zhí)行,一個(gè)程序可對(duì)應(yīng)多個(gè)進(jìn)程;經(jīng)過調(diào)用關(guān)系,一個(gè)進(jìn)程可包含多個(gè)程序。第10頁4.處理機(jī)調(diào)度器(dispatcher)把處理機(jī)從一個(gè)進(jìn)程切換到另一個(gè)進(jìn)程;預(yù)防某進(jìn)程獨(dú)占處理機(jī);處理機(jī)調(diào)度器是操作系統(tǒng)中一段代碼,它完成以下功效:第11頁5.進(jìn)程控制塊

(PCB,processcontrolblock)每個(gè)進(jìn)程在OS中記錄表項(xiàng)(可能有總數(shù)目限制),OS據(jù)此對(duì)進(jìn)程進(jìn)行控制和管理(PCB中內(nèi)容會(huì)動(dòng)態(tài)改變),不一樣OS則不一樣處于關(guān)鍵段,通常不能由應(yīng)用程序本身代碼來直接訪問,而要經(jīng)過系統(tǒng)調(diào)用,或經(jīng)過UNIX中進(jìn)程文件系統(tǒng)(/proc)直接訪問進(jìn)程映象(image)。文件或目錄名為進(jìn)程標(biāo)識(shí)(如:00316),權(quán)限為創(chuàng)建者可讀寫。進(jìn)程控制塊是由OS維護(hù)用來統(tǒng)計(jì)進(jìn)程相關(guān)信息一塊內(nèi)存。第12頁進(jìn)程控制塊內(nèi)容進(jìn)程描述信息:進(jìn)程標(biāo)識(shí)符(processID),唯一,通常是一個(gè)整數(shù);進(jìn)程名,通?;诳蓤?zhí)行文件名(不唯一);用戶標(biāo)識(shí)符(userID);進(jìn)程組關(guān)系(processgroup)進(jìn)程控制信息:當(dāng)前狀態(tài);優(yōu)先級(jí)(priority);代碼執(zhí)行入口地址;程序外存地址;運(yùn)行統(tǒng)計(jì)信息(執(zhí)行時(shí)間、頁面調(diào)度);進(jìn)程間同時(shí)和通信;阻塞原因資源占用信息:虛擬地址空間現(xiàn)實(shí)狀況、打開文件列表CPU現(xiàn)場(chǎng)保護(hù)結(jié)構(gòu):存放器值(通用、程序計(jì)數(shù)器PC、狀態(tài)PSW,地址包含棧指針)第13頁6.PCB組織方式鏈表:同一狀態(tài)進(jìn)程其PCB成一鏈表,多個(gè)狀態(tài)對(duì)應(yīng)多個(gè)不一樣鏈表各狀態(tài)進(jìn)程形成不一樣鏈表:就緒鏈表、阻塞鏈表索引表:同一狀態(tài)進(jìn)程歸入一個(gè)index表(由index指向PCB),多個(gè)狀態(tài)對(duì)應(yīng)多個(gè)不一樣index表各狀態(tài)進(jìn)行形成不一樣索引表:就緒索引表、阻塞索引表第14頁7.進(jìn)程上下文用戶級(jí)上下文:進(jìn)程用戶地址空間(包含用戶棧各層次),包含用戶正文段、用戶數(shù)據(jù)段和用戶棧;存放器級(jí)上下文:程序存放器、處理機(jī)狀態(tài)存放器、棧指針、通用存放器值;系統(tǒng)級(jí)上下文:靜態(tài)部分(PCB和資源表格)動(dòng)態(tài)部分:關(guān)鍵棧(關(guān)鍵過程棧結(jié)構(gòu),不一樣進(jìn)程在調(diào)用相同關(guān)鍵過程時(shí)有不一樣關(guān)鍵棧)進(jìn)程上下文是對(duì)進(jìn)程執(zhí)行活動(dòng)全過程靜態(tài)描述。進(jìn)程上下文由進(jìn)程用戶地址空間內(nèi)容、硬件存放器內(nèi)容及與該進(jìn)程相關(guān)關(guān)鍵數(shù)據(jù)結(jié)構(gòu)組成。第15頁關(guān)鍵態(tài)和用戶態(tài)用戶態(tài)是指進(jìn)程執(zhí)行用戶應(yīng)用程序代碼時(shí)狀態(tài)。處于用戶態(tài)進(jìn)程,不可直接訪問受保護(hù)OS代碼;關(guān)鍵態(tài)是指進(jìn)程經(jīng)過系統(tǒng)調(diào)用來執(zhí)行操作系統(tǒng)代碼時(shí)狀態(tài)。處于關(guān)鍵態(tài)進(jìn)程執(zhí)行代碼是OS代碼,能夠訪問整個(gè)進(jìn)程全部地址空間。第16頁4.1.3進(jìn)程狀態(tài)轉(zhuǎn)換兩狀態(tài)進(jìn)程模型五狀態(tài)進(jìn)程模型掛起進(jìn)程模型第17頁兩狀態(tài)進(jìn)程模型第18頁1.狀態(tài)運(yùn)行狀態(tài)(Running):占用處理機(jī)資源;暫停狀態(tài)(Not-Running):等候進(jìn)程調(diào)度分配處理機(jī)資源;第19頁2.轉(zhuǎn)換進(jìn)程創(chuàng)建(Enter):系統(tǒng)創(chuàng)建進(jìn)程,形成PCB,分配所需資源,排入暫停進(jìn)程表(可為一個(gè)隊(duì)列);調(diào)度運(yùn)行(Dispatch):從暫停進(jìn)程表中選擇一個(gè)進(jìn)程(要求已完成I/O操作),進(jìn)入運(yùn)行狀態(tài);暫停運(yùn)行(Pause):用完時(shí)間片或開啟I/O操作后,放棄處理機(jī),進(jìn)入暫停進(jìn)程表;進(jìn)程結(jié)束(Exit):進(jìn)程運(yùn)行中止;第20頁五狀態(tài)進(jìn)程模型兩狀態(tài)模型無法區(qū)分暫停進(jìn)程表中可運(yùn)行和阻塞,五狀態(tài)模型就是對(duì)暫停狀態(tài)細(xì)化。五狀態(tài)進(jìn)程模型(狀態(tài)變遷)第21頁五狀態(tài)進(jìn)程模型(單隊(duì)列結(jié)構(gòu))第22頁五狀態(tài)進(jìn)程模型(多隊(duì)列結(jié)構(gòu))第23頁1.狀態(tài)運(yùn)行狀態(tài)(Running):占用處理機(jī)資源;處于此狀態(tài)進(jìn)程數(shù)目小于等于CPU數(shù)目。在沒有其它進(jìn)程能夠執(zhí)行時(shí)(如全部進(jìn)程都在阻塞狀態(tài)),通常會(huì)自動(dòng)執(zhí)行系統(tǒng)空閑進(jìn)程(相當(dāng)于空操作)。就緒狀態(tài)(Ready):進(jìn)程已取得除處理機(jī)外所需資源,等候分配處理機(jī)資源;只要分配CPU就可執(zhí)行。能夠按多個(gè)優(yōu)先級(jí)來劃分隊(duì)列,如:時(shí)間片用完->低優(yōu),I/O完成->中優(yōu),頁面調(diào)入完成->高優(yōu)阻塞狀態(tài)(Blocked):因?yàn)檫M(jìn)程等候某種條件(如I/O操作或進(jìn)程同時(shí)),在條件滿足之前無法繼續(xù)執(zhí)行。該事件發(fā)生前即使把處理機(jī)分配給該進(jìn)程,也無法運(yùn)行。如:等候I/O操作完成。第24頁創(chuàng)建狀態(tài)(New):進(jìn)程剛創(chuàng)建,但還不能運(yùn)行(一個(gè)可能原因是OS對(duì)并發(fā)進(jìn)程數(shù)限制);如:分配和建立PCB表項(xiàng)(可能有數(shù)目限制)、建立資源表格(如打開文件表)并分配資源,加載程序并建立地址空間表。結(jié)束狀態(tài)(Exit):進(jìn)程已結(jié)束運(yùn)行,回收除PCB之外其它資源,并讓其它進(jìn)程從PCB中搜集相關(guān)信息(如記帳,將退出碼exitcode傳遞給父進(jìn)程)。第25頁2.轉(zhuǎn)換創(chuàng)建新進(jìn)程:創(chuàng)建一個(gè)新進(jìn)程,以運(yùn)行一個(gè)程序??赡茉?yàn)椋河脩舻卿?、OS創(chuàng)建以提供某項(xiàng)服務(wù)、批處理作業(yè)。收容(Admit,也稱為提交):收容一個(gè)新進(jìn)程,進(jìn)入就緒狀態(tài)。因?yàn)樾阅?、?nèi)存、進(jìn)程總數(shù)等原因,系統(tǒng)會(huì)限制并發(fā)進(jìn)程總數(shù)。調(diào)度運(yùn)行(Dispatch):從就緒進(jìn)程表中選擇一個(gè)進(jìn)程,進(jìn)入運(yùn)行狀態(tài);釋放(Release):因?yàn)檫M(jìn)程完成或失敗而中止進(jìn)程運(yùn)行,進(jìn)入結(jié)束狀態(tài);運(yùn)行到結(jié)束:分為正常退出Exit和異常退出abort(執(zhí)行超時(shí)或內(nèi)存不夠,非法指令或地址,I/O失敗,被其它進(jìn)程所終止)就緒或阻塞到結(jié)束:可能原因有:父進(jìn)程可在任何時(shí)間中止子進(jìn)程;第26頁超時(shí)(Timeout):因?yàn)橛猛陼r(shí)間片或高優(yōu)先進(jìn)程就緒(被搶先)等造成進(jìn)程暫停運(yùn)行;事件等候(EventWait):進(jìn)程要求事件未出現(xiàn)而進(jìn)入阻塞;可能原因包含:申請(qǐng)系統(tǒng)服務(wù)或資源、通信、I/O操作等;事件出現(xiàn)(EventOccurs):進(jìn)程等候事件出現(xiàn);如:操作完成、申請(qǐng)成功等;注:對(duì)于五狀態(tài)進(jìn)程模型,一個(gè)主要問題是當(dāng)一個(gè)事件出現(xiàn)時(shí)怎樣檢驗(yàn)阻塞進(jìn)程表中進(jìn)程狀態(tài)。當(dāng)進(jìn)程多時(shí),對(duì)系統(tǒng)性能影響很大。一個(gè)可能作法是按等候事件類型,排成多個(gè)隊(duì)列。第27頁掛起進(jìn)程模型這個(gè)問題出現(xiàn)是因?yàn)檫M(jìn)程優(yōu)先級(jí)引入,一些低優(yōu)先級(jí)進(jìn)程可能等候較長(zhǎng)時(shí)間,從而被對(duì)換至外存。這么做目標(biāo)是:提升處理機(jī)效率:就緒進(jìn)程表為空時(shí),沒有可運(yùn)行進(jìn)程。經(jīng)過提交新進(jìn)程,可提升處理機(jī)效率;為運(yùn)行進(jìn)程提供足夠內(nèi)存:資源擔(dān)心時(shí),暫停一些進(jìn)程,如:CPU繁忙(或?qū)崟r(shí)任務(wù)執(zhí)行),內(nèi)存擔(dān)心用于調(diào)試:在調(diào)試時(shí),掛起被調(diào)試進(jìn)程(從而對(duì)其地址空間進(jìn)行讀寫)第28頁單掛起進(jìn)程模型第29頁雙掛起進(jìn)程模型第30頁1.狀態(tài)就緒狀態(tài)(Ready):進(jìn)程在內(nèi)存且可馬上進(jìn)入運(yùn)行狀態(tài);阻塞狀態(tài)(Blocked):進(jìn)程在內(nèi)存并等候某事件出現(xiàn);阻塞掛起狀態(tài)(Blocked,suspend):進(jìn)程在外存并等候某事件出現(xiàn);就緒掛起狀態(tài)(Ready,suspend):進(jìn)程在外存,但只要進(jìn)入內(nèi)存,即可運(yùn)行;注:這里只列出了意義有改變或新狀態(tài)。第31頁2.轉(zhuǎn)換掛起(Suspend):把一個(gè)進(jìn)程從內(nèi)存轉(zhuǎn)到外存;可能有以下幾個(gè)情況:阻塞到阻塞掛起:沒有進(jìn)程處于就緒狀態(tài)或就緒進(jìn)程要求更多內(nèi)存資源時(shí),會(huì)進(jìn)行這種轉(zhuǎn)換,以提交新進(jìn)程或運(yùn)行就緒進(jìn)程;就緒到就緒掛起:當(dāng)有高優(yōu)先級(jí)阻塞(系統(tǒng)認(rèn)為會(huì)很快就緒)進(jìn)程和低優(yōu)先級(jí)就緒進(jìn)程時(shí),系統(tǒng)會(huì)選擇掛起低優(yōu)先級(jí)就緒進(jìn)程;運(yùn)行到就緒掛起:對(duì)搶先式分時(shí)系統(tǒng),當(dāng)有高優(yōu)先級(jí)阻塞掛起進(jìn)程因事件出現(xiàn)而進(jìn)入就緒掛起時(shí),系統(tǒng)可能會(huì)把運(yùn)行進(jìn)程轉(zhuǎn)到就緒掛起狀態(tài);第32頁激活(Activate):把一個(gè)進(jìn)程從外存轉(zhuǎn)到內(nèi)存;可能有以下幾個(gè)情況:就緒掛起到就緒:沒有就緒進(jìn)程或掛起就緒進(jìn)程優(yōu)先級(jí)高于就緒進(jìn)程時(shí),會(huì)進(jìn)行這種轉(zhuǎn)換;阻塞掛起到阻塞:當(dāng)一個(gè)進(jìn)程釋放足夠內(nèi)存時(shí),系統(tǒng)會(huì)把一個(gè)高優(yōu)先級(jí)阻塞掛起(系統(tǒng)認(rèn)為會(huì)很快出現(xiàn)所等候事件)進(jìn)程;第33頁事件出現(xiàn)(EventOccurs):進(jìn)程等候事件出現(xiàn);如:操作完成、申請(qǐng)成功等;可能情況有:阻塞到就緒:針對(duì)內(nèi)存進(jìn)程事件出現(xiàn);阻塞掛起到就緒掛起:針對(duì)外存進(jìn)程事件出現(xiàn);收容(Admit):收容一個(gè)新進(jìn)程,進(jìn)入就緒狀態(tài)或就緒掛起狀態(tài)。進(jìn)入就緒掛起原因是系統(tǒng)希望保持一個(gè)大就緒進(jìn)程表(掛起和非掛起);第34頁4.1.4操作系統(tǒng)代碼執(zhí)行OS和進(jìn)程關(guān)系:OS不作為進(jìn)程地址空間一部分:傳統(tǒng)方法。OS作為進(jìn)程地址空間一部分:如UNIXOS功效分別在關(guān)鍵和系統(tǒng)服務(wù)進(jìn)程中,只有OS關(guān)鍵作為進(jìn)程地址空間一部分:如WindowsNT通常,OS關(guān)鍵不是一個(gè)進(jìn)程,其執(zhí)行不被調(diào)度。第35頁4.2進(jìn)程控制4.2.1進(jìn)程控制功效4.2.2進(jìn)程創(chuàng)建和退出4.2.3UNIX進(jìn)程阻塞和喚醒4.2.4NT線程掛起和激活4.2.5UNIX進(jìn)程管理舉例4.2.6WindowsNT進(jìn)程管理舉例返回第36頁4.2.1進(jìn)程控制功效完成進(jìn)程狀態(tài)轉(zhuǎn)換。原語(primitive):由若干條指令組成“原子操作(atomicoperation)”過程,作為一個(gè)整體而不可分割--要么全都完成,要么全都不做。許多系統(tǒng)調(diào)用就是原語。注意:系統(tǒng)調(diào)用并不都是原語。進(jìn)程A調(diào)用read(),因無數(shù)據(jù)而阻塞,在read()里未返回。然后進(jìn)程B調(diào)用read(),此時(shí)read()被重入。系統(tǒng)調(diào)用不一定一次執(zhí)行完并返回該進(jìn)程,有可能在特定點(diǎn)暫停,而轉(zhuǎn)入到其它進(jìn)程。第37頁4.2.2進(jìn)程創(chuàng)建和退出1.創(chuàng)建繼承(inherit):子進(jìn)程能夠從父進(jìn)程中繼承用戶標(biāo)識(shí)符、環(huán)境變量、打開文件、文件系統(tǒng)當(dāng)前目錄、控制終端、已經(jīng)連接共享存放區(qū)、信號(hào)處理例程入口表等不被繼承:進(jìn)程標(biāo)識(shí)符,父進(jìn)程標(biāo)識(shí)符spawn創(chuàng)建并執(zhí)行一個(gè)新進(jìn)程;新進(jìn)程與父進(jìn)程關(guān)系可有各種:覆蓋(_P_OVERLAY)、并發(fā)(_P_NOWAITor_P_NOWAITO)、父進(jìn)程阻塞(_P_WAIT)、后臺(tái)(_P_DETACH)等。第38頁2.退出也稱為“終止”或主程序返回:調(diào)用exit()可終止進(jìn)程。釋放資源:釋放內(nèi)外存空間關(guān)閉全部打開文件釋放共享內(nèi)存段和各種鎖定lock第39頁4.2.3UNIX進(jìn)程阻塞和喚醒阻塞:暫停一段時(shí)間(sleep);暫停并等候信號(hào)(pause);等候子進(jìn)程暫?;蚪K止(wait);喚醒:發(fā)送信號(hào)到某個(gè)或一組進(jìn)程(kill)第40頁調(diào)用wait掛起本進(jìn)程以等候子進(jìn)程結(jié)束,子進(jìn)程結(jié)束時(shí)返回。父進(jìn)程創(chuàng)建多個(gè)子進(jìn)程且已經(jīng)有某子進(jìn)程退出時(shí),父進(jìn)程中wait函數(shù)在第一個(gè)子進(jìn)程結(jié)束時(shí)返回。其調(diào)用格式為"pid_twait(int*stat_loc);";返回值為子進(jìn)程ID。waitpid()等候指定進(jìn)程號(hào)子進(jìn)程返回并修改狀態(tài);waitid()等候子進(jìn)程修改狀態(tài);調(diào)用pause掛起本進(jìn)程以等候信號(hào),接收到信號(hào)后恢復(fù)執(zhí)行。當(dāng)接收到中止進(jìn)程信號(hào)時(shí),該調(diào)用不再返回。其調(diào)用格式為"intpause(void);";第41頁調(diào)用sleep將在指定時(shí)間seconds內(nèi)掛起本進(jìn)程。其調(diào)用格式為:"unsignedsleep(unsignedseconds);";返回值為實(shí)際掛起時(shí)間。調(diào)用kill可發(fā)送信號(hào)sig到某個(gè)或一組進(jìn)程pid。其調(diào)用格式為:"intkill(pid_tpid,intsig);"。信號(hào)定義在文件"/usr/include/asm/signal.h"中。命令"kill"可用于向進(jìn)程發(fā)送信號(hào)。如:"kill-9100"將發(fā)送SIGKILL到ID為100進(jìn)程;該命令將中止該進(jìn)程執(zhí)行。第42頁實(shí)例:UNIX_wait演示子進(jìn)程與父進(jìn)程關(guān)系和fork、exec、wait使用;程序main.c功效是進(jìn)行10次循環(huán),創(chuàng)建2個(gè)子進(jìn)程。循環(huán)到第3次時(shí),等候子進(jìn)程結(jié)束。#include<sys/types.h>#include<unistd.h>#include<stdio.h>#include<sys/wait.h>pid_twait(int*stat_loc);voidperror(constchar*s);#include<errno.h>interrno;intglobal;第43頁main(){intlocal,i;pid_tchild;

if((child=fork())==-1){ //創(chuàng)建失敗printf("ForkError.\n");}if(child==0){//子進(jìn)程printf("Nowitisinchildprocess.\n");if(execl("/home/xyong/work/ttt","ttt",NULL)==-1) { //加載程序失敗 perror("Errorinchildprocess"); }global=local+2;exit();}第44頁//父進(jìn)程printf("Nowitisinparentprocess.\n");for(i=0;i<10;i++){ sleep(2); printf("Parent:%d\n",i); if(i==2) {if((child=fork())==-1){ //創(chuàng)建失敗printf("ForkError.\n");}if(child==0){//子進(jìn)程printf("Nowitisinchildprocess.\n");if(execl("/home/xyong/work/ttt","ttt",NULL)==-1) { //加載程序失敗 perror("Errorinchildprocess"); }global=local+2;exit();} }第45頁 if(i==3) { pid_ttemp; temp=wait(NULL); printf("ChildprocessID:%d\n",temp); }}global=local+1;exit();}第46頁程序test.c#include<sys/types.h>#include<unistd.h>pid_tgetpid(void);pid_tgetppid(void);intglobal;main(){intlocal;inti;pid_tCurrentProcessID,ParentProcessID;CurrentProcessID=getpid();ParentProcessID=getppid();printf("NowitisintheprogramTEST.\n");for(i=0;i<10;i++){ sleep(2); printf("Parent:%d,Current:%d,Nunber:%d\n",ParentProcessID, CurrentProcessID,i);}global=local+1;exit();}功效是進(jìn)行10次循環(huán)。第47頁結(jié)果Parent:7072,Current:7074,Nunber:4Parent:7072,Current:7073,Nunber:8Parent:7072,Current:7074,Nunber:5Parent:7072,Current:7073,Nunber:9ChildprocessID:7073Parent:7072,Current:7074,Nunber:6Parent:4Parent:7072,Current:7074,Nunber:7Parent:5Parent:7072,Current:7074,Nunber:8Parent:6Parent:7072,Current:7074,Nunber:9Parent:7Parent:8Parent:9Nowitisinparentprocess.Nowitisinchildprocess.NowitisintheprogramTEST.Parent:0Parent:7072,Current:7073,Nunber:0Parent:1Parent:7072,Current:7073,Nunber:1Parent:2Parent:7072,Current:7073,Nunber:2Nowitisinchildprocess.NowitisintheprogramTEST.Parent:7072,Current:7073,Nunber:3Parent:3Parent:7072,Current:7074,Nunber:0Parent:7072,Current:7073,Nunber:4Parent:7072,Current:7074,Nunber:1Parent:7072,Current:7073,Nunber:5Parent:7072,Current:7074,Nunber:2Parent:7072,Current:7073,Nunber:6Parent:7072,Current:7074,Nunber:3Parent:7072,Current:7073,Nunber:7第48頁4.2.4NT線程掛起和激活NT中處理機(jī)分配對(duì)象為線程,一個(gè)線程可被屢次掛起和屢次激活。在線程內(nèi)有一個(gè)掛起計(jì)數(shù)(suspendcount),掛起操作使該計(jì)數(shù)加1,激活操作便該計(jì)數(shù)減1;當(dāng)掛起計(jì)數(shù)為0時(shí),線程恢復(fù)執(zhí)行。(1)掛起:WindowsNT中SuspendThread可掛起指定線程;DWORDSuspendThread(HANDLEhThread//handletothethread);(2)激活:WindowsNT中ResumeThread可恢復(fù)指定線程執(zhí)行;DWORDResumeThread(HANDLEhThread//identifiesthreadtorestart);第49頁例子NT_thread.cpp#include<stdio.h>#include<windows.h>#include<iostream.h>#include<winbase.h>voidSubThread(void){ inti; for(i=0;i<5;i++) { cout<<"SubThread"<<i<<endl; Sleep(); }}第50頁voidmain(void){cout<<"CreateThread"<<endl; //Createathread; DWORDIDThread; HANDLEhThread; hThread=CreateThread(NULL,//nosecurityattributes0,//usedefaultstacksize(LPTHREAD_START_ROUTINE)SubThread,//threadfunctionNULL,//nothreadfunctionargument0,//usedefaultcreationflags&IDThread);//returnsthreadidentifier

//Checkthereturnvalueforsuccess. if(hThread==NULL) cout<<"CreateThreaderror"<<endl;第51頁 inti; for(i=0;i<5;i++) { cout<<"MainThread"<<i<<endl; if(i==1) { if(SuspendThread(hThread)==0xFFFFFFFF) { cout<<"Suspendthreaderror."<<endl; } else { cout<<"Suspendthreadisok."<<endl; } }第52頁 if(i==3) { if(ResumeThread(hThread)==0xFFFFFFFF) { cout<<"Resumethreaderror."<<endl; } else { cout<<"Resumethreadisok."<<endl; } } Sleep(4000); }}第53頁運(yùn)行結(jié)果CreateThreadMainThread0SubThread0SubThread1MainThread1Suspendthreadisok.MainThread2MainThread3Resumethreadisok.SubThread2SubThread3MainThread4SubThread4第54頁4.2.5UNIX進(jìn)程管理舉例進(jìn)程上下文:指進(jìn)程用戶地址空間內(nèi)容、存放器內(nèi)容及與進(jìn)程相關(guān)關(guān)鍵數(shù)據(jù)結(jié)構(gòu);包含三部分"上下文":用戶級(jí)、存放器級(jí)、系統(tǒng)級(jí)用戶級(jí)上下文:正文段即代碼(text);數(shù)據(jù)段(data);棧段(userstack):用戶態(tài)執(zhí)行時(shí)過程調(diào)用;共享存放區(qū)(sharedmemory)把地址空間段稱為"區(qū)(region)":進(jìn)程區(qū)表和系統(tǒng)區(qū)表(前者索引指向后者)系統(tǒng)上下文:proc結(jié)構(gòu):總在內(nèi)存,內(nèi)容包含阻塞原因;user結(jié)構(gòu):能夠調(diào)出到外存,進(jìn)程處于執(zhí)行狀態(tài)時(shí)才用得著,各種資源表格;進(jìn)程區(qū)表:從虛擬地址到物理地址映射;關(guān)鍵棧:關(guān)鍵態(tài)執(zhí)行時(shí)過程調(diào)用棧結(jié)構(gòu);1.進(jìn)程結(jié)構(gòu)第55頁2.進(jìn)程狀態(tài)轉(zhuǎn)換注意:狀態(tài)“被搶先”與“內(nèi)存就緒”地位相同,要等到下一次進(jìn)程調(diào)度時(shí),才能回到“用戶態(tài)執(zhí)行”。第56頁3.進(jìn)程控制父子進(jìn)程fork()返回值不一樣,ParentPID值不一樣getppid()fork()創(chuàng)建子進(jìn)程之后,執(zhí)行返回父進(jìn)程,或調(diào)度切換到子進(jìn)程以及其它進(jìn)程fork創(chuàng)建一個(gè)新進(jìn)程(子進(jìn)程),子進(jìn)程是父進(jìn)程準(zhǔn)確復(fù)制。在子進(jìn)程中返回為0;在父進(jìn)程中,返回子進(jìn)程標(biāo)識(shí)。子進(jìn)程是從fork調(diào)用返回時(shí)在用戶態(tài)開始運(yùn)行。父進(jìn)程返回點(diǎn)與子進(jìn)程開始點(diǎn)是相同。exec用一個(gè)新進(jìn)程覆蓋調(diào)用進(jìn)程。它參數(shù)包含新進(jìn)程對(duì)應(yīng)文件和命令行參數(shù)。成功調(diào)用時(shí),不再返回;不然,返回犯錯(cuò)原因。創(chuàng)建:fork(),exec()第57頁UNIX進(jìn)程創(chuàng)建第58頁退出:exit()向父進(jìn)程給出一個(gè)退出碼(8位整數(shù))。父進(jìn)程終止時(shí)怎樣影響子進(jìn)程:子進(jìn)程從父進(jìn)程繼承了進(jìn)程組ID和終端組ID(控制終端),所以子進(jìn)程對(duì)發(fā)給該進(jìn)程組或終端組信號(hào)敏感。終端關(guān)閉時(shí),以該終端為控制終端全部進(jìn)程都收到SIGHUP信號(hào)。子進(jìn)程終止時(shí),向父進(jìn)程發(fā)送SIGCHLD信號(hào),父進(jìn)程截獲此信號(hào)并經(jīng)過wait3()系統(tǒng)調(diào)用來釋放子進(jìn)程PCB。第59頁阻塞:暫停一段時(shí)間sleep;暫停并等候信號(hào)pause;等候子進(jìn)程暫?;蚪K止wait:能夠取得子進(jìn)程退出碼(16位整數(shù):exit退出時(shí)exitCode*256,信號(hào)終止時(shí)coreFlag*128+signalNumber,信號(hào)停頓時(shí)signalNumber*256+0x7f)喚醒:發(fā)送信號(hào)到某個(gè)或一組進(jìn)程kill:使得接收方從阻塞系統(tǒng)調(diào)用中返回(如read返回并給出失敗值-1),并隨即調(diào)用對(duì)應(yīng)信號(hào)處理例程調(diào)試:設(shè)置執(zhí)行斷點(diǎn)(breakpoint),讀寫進(jìn)程映象中數(shù)據(jù)(從而修改進(jìn)程上下文)。系統(tǒng)調(diào)用ptrace(),信號(hào)SIGTRAP(由調(diào)試方發(fā)送到被調(diào)試方)ptrace允許父進(jìn)程控制子進(jìn)程運(yùn)行,可用于調(diào)試。子進(jìn)程在碰到signal時(shí)暫停,父進(jìn)程可訪問coreimage。第60頁4.2.6WindowsNT進(jìn)程管理舉例NT進(jìn)程和線程作為對(duì)象(Object),以句柄(handle)來引用。對(duì)應(yīng)地有控制對(duì)象服務(wù)(services)。進(jìn)程對(duì)象屬性;PID,AccessToken,BasePriority,默認(rèn)處理器集合等1.概述第61頁NT進(jìn)程關(guān)系對(duì)NT關(guān)鍵而言,進(jìn)程之間沒有任何關(guān)系(包含父子關(guān)系)。那么,怎樣表示UNIX進(jìn)程之間父子關(guān)系(以及其它關(guān)系)?由POSIX子系統(tǒng)來建立和維護(hù)NTNativeAPI:內(nèi)查對(duì)上API和Win32子系統(tǒng)API/ntw2k/info/ntdll.shtml第62頁2.NT進(jìn)程結(jié)構(gòu)第63頁DataStructuresforeachprocess/threadExecutiveprocessblock(EPROCESS)Executivethreadblock(ETHREAD)Win32processblockProcessenvironmentblockThreadenvironmentblockProcessenvironmentblockThreadenvironmentblockProcessblock(EPROCESS)Threadblock(ETHREAD)Win32processblockHandletable...ProcessaddressspaceSystemaddressspaceRef:WindowsInternals-P290第64頁3.進(jìn)程控制創(chuàng)建:CreateProcess()函數(shù)用于創(chuàng)建新進(jìn)程及其根本程,以執(zhí)行指定程序。新進(jìn)程能夠繼承:打開文件句柄、各種對(duì)象(如進(jìn)程、線程、信號(hào)量、管道等)句柄、環(huán)境變量、當(dāng)前目錄、原進(jìn)程控制終端、原進(jìn)程進(jìn)程組(用于發(fā)送Ctrl+C或Ctrl+Break信號(hào)給多個(gè)進(jìn)程)--每個(gè)句柄在創(chuàng)建或打開時(shí)能指定是否可繼承;新進(jìn)程不能繼承:優(yōu)先權(quán)類、內(nèi)存句柄、DLL模塊句柄CREATE_NEW_CONSOLE表示新進(jìn)程有一個(gè)新控制臺(tái)CREATE_NEW_PROCESS_GROUP表示新進(jìn)程是一個(gè)新進(jìn)程組根。第65頁退出:ExitProcess()或TerminateProcess(),進(jìn)程包含線程全部終止;ExitProcess()終止一個(gè)進(jìn)程和它全部線程;它終止操作是完整,包含關(guān)閉全部對(duì)象句柄、它全部線程等;TerminateProcess()終止指定進(jìn)程和它全部線程;它終止操作是不完整(如:不向相關(guān)DLL通報(bào)關(guān)閉情況),通常只用于異常情況下對(duì)進(jìn)程終止。第66頁4.調(diào)試進(jìn)程對(duì)象屬性包含:調(diào)試時(shí)用于通知另一進(jìn)程(調(diào)試器)IPCchannel調(diào)試器在CreateProcess時(shí)指定DEBUG_PROCESS標(biāo)志或利用DebugActiveProcess()函數(shù),可在調(diào)用者(debugger)與被調(diào)用者(target)間建立調(diào)試關(guān)系,target會(huì)向debugger通報(bào)全部調(diào)試事件;被調(diào)試進(jìn)程向調(diào)試器進(jìn)程發(fā)送調(diào)試事件,包含:創(chuàng)建新進(jìn)程、新線程、加載DLL、執(zhí)行斷點(diǎn)等。調(diào)試器經(jīng)過WaitForDebugEvent()和ContinueDebugEvent()組成事件循環(huán)。WaitForDebugEvent()可在指定時(shí)間內(nèi)等候可能調(diào)試事件;ContinueDebugEvent()可使被調(diào)試事件暫停進(jìn)程繼續(xù)運(yùn)行。經(jīng)過ReadProcessMemory()和WriteProcessMemory()來讀寫被調(diào)試進(jìn)程存放空間。第67頁4.3線程(THREAD)4.3.1線程引入4.3.2進(jìn)程和線程比較4.3.3線程舉例返回引入線程目標(biāo)是簡(jiǎn)化同一進(jìn)程內(nèi)各線程間通信,以小開銷來提升進(jìn)程內(nèi)并發(fā)程度。第68頁4.3.1線程引入進(jìn)程:資源分配單位(存放器、文件)和CPU調(diào)度(分配)單位。又稱為"任務(wù)(task)"線程:進(jìn)程中描述指令并發(fā)執(zhí)行過程動(dòng)態(tài)對(duì)象,是CPU調(diào)度單位。只擁有必不可少資源,如:線程狀態(tài)、存放器上下文和棧一樣含有就緒、阻塞和執(zhí)行三種基本狀態(tài)一個(gè)進(jìn)程中最少有一個(gè)線程,每個(gè)線程對(duì)應(yīng)于一個(gè)當(dāng)前指令指針;線程優(yōu)點(diǎn):減小并發(fā)執(zhí)行時(shí)間和空間開銷(線程創(chuàng)建、退出和調(diào)度),所以允許在系統(tǒng)中建立更多線程來提升并發(fā)程度。線程創(chuàng)建時(shí)間比進(jìn)程短;線程終止時(shí)間比進(jìn)程短;同進(jìn)程內(nèi)線程切換時(shí)間比進(jìn)程短;因?yàn)橥M(jìn)程內(nèi)線程間共享內(nèi)存和文件資源,可直接進(jìn)行不經(jīng)過內(nèi)核通信;第69頁進(jìn)程與線程關(guān)系第70頁OS對(duì)線程實(shí)現(xiàn)方式內(nèi)核維護(hù)進(jìn)程和線程上下文信息;線程切換由內(nèi)核完成;一個(gè)線程發(fā)起系統(tǒng)調(diào)用而阻塞,不會(huì)影響其它線程運(yùn)行。時(shí)間片分配給線程,所以多線程進(jìn)程取得更多CPU時(shí)間。依賴于OS關(guān)鍵,由內(nèi)核內(nèi)部需求進(jìn)行創(chuàng)建和撤消,用來執(zhí)行一個(gè)指定函數(shù)。WindowsNT和OS/2支持內(nèi)核線程;內(nèi)核線程(kernel-levelthread)第71頁用戶線程(user-levelthread)用戶線程維護(hù)由應(yīng)用進(jìn)程完成;內(nèi)核不了解用戶線程存在;用戶線程切換不需要內(nèi)核特權(quán);用戶線程調(diào)度算法可針對(duì)應(yīng)用優(yōu)化;不依賴于OS關(guān)鍵,應(yīng)用進(jìn)程利用線程庫(kù)提供創(chuàng)建、同時(shí)、調(diào)度和管理線程函數(shù)來控制用戶線程。如:數(shù)據(jù)庫(kù)系統(tǒng)informix,圖形處理AldusPageMaker。調(diào)度由應(yīng)用軟件內(nèi)部進(jìn)行,通常采取非搶先式和更簡(jiǎn)單規(guī)則,也無需用戶態(tài)/關(guān)鍵態(tài)切換,所以速度尤其快。一個(gè)線程發(fā)起系統(tǒng)調(diào)用而阻塞,則整個(gè)進(jìn)程在等候。時(shí)間片分配給進(jìn)程,多線程則每個(gè)線程就慢。第72頁輕權(quán)進(jìn)程(LightWeightProcess)它是內(nèi)核支持用戶線程。一個(gè)進(jìn)程可有一個(gè)或多個(gè)輕權(quán)進(jìn)程,每個(gè)輕權(quán)進(jìn)程由一個(gè)單獨(dú)內(nèi)核線程來支持。第73頁4.3.2進(jìn)程和線程比較地址空間和其它資源(如打開文件):進(jìn)程間相互獨(dú)立,同一進(jìn)程各線程間共享某進(jìn)程內(nèi)線程在其它進(jìn)程不可見通信:進(jìn)程間通信IPC,線程間能夠直接讀寫進(jìn)程數(shù)據(jù)段(如全局變量)來進(jìn)行通信需要進(jìn)程同時(shí)和互斥伎倆輔助,以確保數(shù)據(jù)一致性調(diào)度:線程上下文切換比進(jìn)程上下文切換要快得多;第74頁線程切換和進(jìn)程切換第75頁4.3.3線程舉例1.SUNSolaris10Solaris支持內(nèi)核線程(Kernelthreads)、輕權(quán)進(jìn)程(LightweightProcesses)和用戶線程(UserLevelThreads)。一個(gè)進(jìn)程可有大量用戶線程;用戶線程與輕權(quán)進(jìn)程一一對(duì)應(yīng),不一樣輕權(quán)進(jìn)程分別對(duì)應(yīng)不一樣內(nèi)核線程。第76頁SolarisProcessModelSolarisKernelisMulti-threadedKernellevelthreads(kthreads)aretheunitofconcurrencywithinthekernelScheduling,synchronizationarekernel-level(kthread)conceptsProcessesareacombinationofstateandoneormoreuserthreadsProcessthreadsareabstracteduponkernelthreadsSinglethreadedprocesseshavejustonethread第77頁TheProcessModelProcessesAllprocessesbeginlifeasaprogram,adiskfile(ELFobject)Allprocesseshave“state”orcontextthatdefinestheirexecutionenvironment-hardware&softwarecontextHardwarecontextTheprocessorstate,whichisCPUarchitecturedependent.Ingeneral,thestateofthehardwareregisters(generalregisters,privilegedregisters)MaintainedintheLWPSoftwarecontextAddressspace,credentials,openfiles,resourcelimits,etc–stuffsharedbyallthethreadsinaprocess第78頁ConceptualViewofaProcess第79頁P(yáng)rocstructuredefinethecontextandexecutionenvironmentuareaisembeddedintheprocessstructure—cesskernelStackintheLWP第80頁P(yáng)rocessExecutionEnvironmentMappedmemorypagesforprocess’svariousaddressspacesegmentsIdentifiers第81頁P(yáng)rocessStateDiagramForthemostpart,foreachprocessstate,thereisacorrespondingkthreadstateSomewhatmisleading-kthreadschangestate,notprocessesLink:SolarisKernelThreadState第82頁P(yáng)rocessandKernelThreadStatesKthreadcreationisnotflaggedasadistinctstate-theygorighttoTS_RUNKthreadstructuresareflaggedasTS_FREEwhentheprocorkthread/LWPisterminatedThisallowsthekerneltomaintainacacheoffreekthread/LWPstructures第83頁P(yáng)rocess,LWP,andKthreadLinkageKernelmaintainssystem-widelinkedlistsofprocesses,LWPsandkthreadsRelationshiplinksmaintainedateverylevel第84頁SolarisThreadConceptsKernelThreadsKernel’sunitofconcurrencyLWPImplementedtoallowconcurrentsystemcallsfromasingleprocessWithoutLWPs,userthreadswouldcontendatsystemcallUserThreadsThethreadabstractionoftheuserprogrammingmodel第85頁TheLightweightProcess(LWP)theattributeofaLWPResourceutilizationcountersandmicrostateaccountinginformationThesumtotalofallLWPsresourceusageisstoredintheprocessMostoftheLWPstructuremembersexisttosupportsystemcallsandtomaintainhardwarecontextinformationAnLWPblockedonasystemcalldoesnotcausetheentireprocesstoblock第86頁Thekernelthread(KThread)Featurestheentitythatactuallygetsputonadispatchqueueandscheduledschedulingclassandpriorityisassignedtoakthread,nottheprocesskthreadassociatedwiththeLWP,hasa

溫馨提示

  • 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. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論