




版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
目錄27544_WPSOffice_Level1一、實驗一Windows進程管理 113505_WPSOffice_Level1·實驗目的、實驗內(nèi)容 15203_WPSOffice_Level1·實驗結果與分析 35438_WPSOffice_Level1·小結與心得體會 41845_WPSOffice_Level1二、實驗二Linux進程管理 512661_WPSOffice_Level1·實驗目的、實驗內(nèi)容 528700_WPSOffice_Level1·實驗結果與分析 715196_WPSOffice_Level1·小結與心得體會 817839_WPSOffice_Level1三、實驗三Linux進程間通信 97535_WPSOffice_Level1·實驗目的、實驗內(nèi)容 126452_WPSOffice_Level1·實驗結果與分析 1118781_WPSOffice_Level1·小結與心得體會 1119424_WPSOffice_Level1四、實驗四Windows的互斥與同步 126319_WPSOffice_Level1·實驗目的、實驗內(nèi)容 1227420_WPSOffice_Level1·實驗結果與分析 1410113_WPSOffice_Level1·小結與心得體會 155754_WPSOffice_Level1五、實驗六銀行家算法的模擬與實現(xiàn) 1625993_WPSOffice_Level1·實驗目的 1619230_WPSOffice_Level1·總體設計 1628167_WPSOffice_Level1·詳細設計 1726240_WPSOffice_Level1·實驗結果與分析 181257_WPSOffice_Level1·小結與心得體會 1920449_WPSOffice_Level1六、實驗八磁盤調(diào)度算法的模擬與實現(xiàn) 20843_WPSOffice_Level1·實驗目的 2022348_WPSOffice_Level1·總體設計 2020226_WPSOffice_Level1·詳細設計 214450_WPSOffice_Level1·實驗結果與分析 2232680_WPSOffice_Level1·小結與心得體會 2316088_WPSOffice_Level1七、實驗九*基于信號量機制的并發(fā)程序設計 249396_WPSOffice_Level1·實驗目的 241166_WPSOffice_Level1·總體設計 2432164_WPSOffice_Level1·詳細設計 248610_WPSOffice_Level1·實驗結果與分析 2715442_WPSOffice_Level1·小結與心得體會 2731481_WPSOffice_Level1八、實驗十*簡單shell命令行解釋器的設計與實現(xiàn) 2827347_WPSOffice_Level1·實驗目的 2820483_WPSOffice_Level1·總體設計 286567_WPSOffice_Level1·詳細設計 2819154_WPSOffice_Level1·實驗結果與分析 3024569_WPSOffice_Level1·小結與心得體會 31九、課程設計報告日志 32實驗題目實驗一、Windows進程管理實驗目的學會使用VC編寫基本的Win32ConsolApplication控制臺應用程序)。通過創(chuàng)建進程、觀察正在運行的進程和終止進程的程序設計和調(diào)試操作,進一步熟悉操作系統(tǒng)的進程概念,理解Windows進程的“一生”。通過閱讀和分析實驗程序,學習創(chuàng)建進程、觀察進程、終止進程以及父子進程同步的基本程序設計方法。實驗內(nèi)容1.背景知識:Windows所創(chuàng)建的每個進程都從調(diào)用CreateProcess()API函數(shù)開始,該函數(shù)的任務是在對象管理器子系統(tǒng)內(nèi)初始化進程對象。每一進程都以調(diào)用ExitProcess()或TerminateProcess()API函數(shù)終止。通常應用程序的框架負責調(diào)用ExitProcess()函數(shù)。對于C++運行庫來說,這一調(diào)用發(fā)生在應用程序的main()函數(shù)返回之后。模塊介紹:主函數(shù)模塊、創(chuàng)建子進程、startClone()模塊、互斥信號量的創(chuàng)建與釋放實驗步驟:編寫基本的Win32ConsolApplication創(chuàng)建進程進行父子進程的簡單通信及終止進程數(shù)據(jù)結構數(shù)組以及函數(shù)的調(diào)用父子進程參數(shù)的傳遞父子進程利用互斥信號進行同步互斥體的創(chuàng)建、獲得、檢測與釋放、API接口子進程的創(chuàng)建與關閉程序流程圖:關鍵代碼//清單1-2創(chuàng)建子進程//創(chuàng)建傳遞過來的進程的克隆過程并賦于其ID值voidStartClone(intnCloneID){//提取用于當前可執(zhí)行文件的文件名TCHARszFilename[MAX_PATH];GetModuleFileName(NULL,szFilename,MAX_PATH);//格式化用于子進程的命令行并通知其EXE文件名和克隆IDTCHARszCmdLine[MAX_PATH]; sprintf(szCmdLine,"\"%s\"%d",szFilename,nCloneID); //用于子進程的STARTUPINFO結構STARTUPINFOsi;ZeroMemory(&si,sizeof(si));si.cb=sizeof(si); //必須是本結構的大小//返回的用于子進程的進程信息PROCESS_INFORMATIONpi;//利用同樣的可執(zhí)行文件和命令行創(chuàng)建進程,并賦于其子進程的性質BOOLbCreateOK=::CreateProcess(szFilename, //產(chǎn)生這個EXE的應用程序的名稱szCmdLine, //告訴其行為像一個子進程的標志NULL, //缺省的進程安全性NULL, //缺省的線程安全性FALSE, //不繼承句柄CREATE_NEW_CONSOLE, //使用新的控制臺NULL, //新的環(huán)境NULL, //當前目錄&si, //啟動信息&pi); //返回的進程信息//對子進程釋放引用if(bCreateOK){CloseHandle(pi.hProcess);CloseHandle(pi.hThread);}}實驗結果與分析實驗1-1結果分析:其中出現(xiàn)的問題就是要將void改成int,然后加上return0,從main()函數(shù)開始,程序將會運行輸出Hello,Win32ConsolApplication。問題:如果運行不成功,則可能的原因是什么?答:原因可能是編譯器的不同導致兼容性不同,編譯出錯;還有就是創(chuàng)建項目出錯,不對應無法運行。實驗1-2結果分析:從main()函數(shù)開始,首先判斷argc的值(argc初始值默認為1)因為argc不滿足大于1,所以不能將argv[1]賦值給nClone;然后nClone<c_nCloneMax,則調(diào)用StartClone(++nClone)函數(shù),創(chuàng)建子進程;創(chuàng)建子進程后,argc的值變?yōu)?,然后將自增的nClone賦值argv[1],然后將繼續(xù)執(zhí)行main()函數(shù),直到(nClone>c_nCloneMax),跳出,結束創(chuàng)建新進程。最初結果與第一次修改結果相同:(出現(xiàn)六個進程)第二次修改結果:(無限產(chǎn)生進程)問題:從中你可以得出什么結論?說明nClone的作用。變量的定義和初始化方法(位置)對程序的執(zhí)行結果有影響嗎?為什么?答:在控制程序執(zhí)行過程,當nClone>5時跳出循環(huán),創(chuàng)建子進程結束;但是當變量賦值的位置不同的時候對于執(zhí)行結果有影響,在第二次更改中,由于nClone每次都初始化為0,會陷入死循環(huán),不斷創(chuàng)建子進程。實驗1-3結果分析:從main()函數(shù)開始,首先判斷argc的值(argc初始值默認為1),決定進行父進程還是子進程,因為argc不滿足大于1,所以調(diào)用parent()函數(shù),在執(zhí)行parent()函數(shù)過程中調(diào)用StartClone();然后通過sprintf(szCmdLine,"\"%s\"child",szFilename)將argv[1]賦值child后面滿足條件后調(diào)用child()函數(shù);由于設置了互斥信號,則只允許一個進程進行,所以只有當父進程釋放互斥信號hMutexSuicide時,子進程檢測獲得才結束進程。最初結果和修改之后的結果:問題:參考MSDN中的幫助文件CreateMutex()、OpenMutex()、ReleaseMutex()和WaitForSingleObject()的使用方法,理解父子進程如何利用互斥體進行同步的。給出父子進程同步過程的一個大概描述。答:CreateMutex()創(chuàng)建互斥體hMutexSuicide信號、OpenMutex()打開互斥體、ReleaseMutex()釋放互斥體、WaitForSingleObject()檢測Hhandle信號狀態(tài),通過這些只允許有一個狀態(tài)被創(chuàng)建或者使用也就是信號量唯一,實現(xiàn)進程的同步。小結與心得體會通過這個實驗讓我更加深入了解了熟悉操作系統(tǒng)的進程這方面的概念,也更加清楚了操作系統(tǒng)進程在各種時期的相關操作與設計,也讓我更加對于操作系統(tǒng)這一學科產(chǎn)生了更加濃厚的興趣。所有進程都是以調(diào)用CreateProcess()API函數(shù)開始的是ExitProcess()函數(shù)結束的,在獲得互斥體時,首先,想要訪問調(diào)用的線程可使用OpenMutex()API來獲得指向對象的句柄;然后,線程將這個句柄提供給一個等待函數(shù)。當內(nèi)核將互斥體對象發(fā)送給等待線程時,就表明該線程獲得了互斥體的擁有權。當線程獲得擁有權時,線程控制了對共享資源的訪問——必須設法盡快地放棄互斥體。放棄共享資源時需要在該對象上調(diào)用ReleaseMute()API。然后系統(tǒng)負責將互斥體擁有權傳遞給下一個等待著的線程(由到達時間決定順序)。還有就是,Windows提供的常用對象可分成三類:核心應用服務、線程同步和線程間通訊。其中,開發(fā)人員要可以使用線程同步對象來協(xié)調(diào)線程和進程的工作,以使其共享信息并執(zhí)行任務。實驗題目實驗二、Linux進程管理實驗目的通過進程的創(chuàng)建、撤銷和運行加深對進程概念和進程并發(fā)執(zhí)行的理解,明確進程和程序之間的區(qū)別。實驗內(nèi)容背景知識fork調(diào)用的一個奇妙之處就是它僅僅被調(diào)用一次,卻能夠返回兩次,它可能有三種不同的返回值:在父進程中,fork返回新創(chuàng)建子進程的進程ID;在子進程中,fork返回0;如果出現(xiàn)錯誤,fork返回一個負值;在fork函數(shù)執(zhí)行完畢后,如果創(chuàng)建新進程成功,則出現(xiàn)兩個進程,一個是子進程,一個是父進程。在子進程中,fork函數(shù)返回0,在父進程中,fork返回新創(chuàng)建子進程的進程ID。我們可以通過fork返回的值來判斷當前進程是子進程還是父進程。模塊介紹2-1:一個父進程,一個子進程2-2:一個父進程,一個子進程實驗步驟創(chuàng)建進程創(chuàng)建子進程執(zhí)行新任務數(shù)據(jù)結構數(shù)據(jù)結構為鏈表結構,C++語言編寫,運用了C++庫函數(shù)。個進程會派生多個子進程時,子進程與子進程具有兄弟關系。程序流程圖關鍵代碼//清單2-2子進程執(zhí)行新任務intmain(){pid_tpid;/*forkachildprocess*/pid=fork(); if(pid<0) {/*erroroccurred*/ fprintf(stderr,"ForkFailed");return1;}elseif(pid==0){/*子進程*/ execlp("/bin/ls","ls",NULL);}else{/*父進程將一直等待,直到子進程運行完畢*/wait(NULL);printf("ChildComplete");}return0;}實驗結果與分析實驗2-1結果分析:從main()函數(shù)開始,運行父進程,接著通過判斷是否創(chuàng)建成功,while((x=fork())==-1)進行判斷,如果x>0,則繼續(xù)創(chuàng)建子進程,若成功,則此時有一個子進程和一個父進程,先創(chuàng)建的子進程會輸出a,接下來是父進程執(zhí)行完畢,輸出b,后面是進程執(zhí)行完畢輸出c;fork出來的進程不能確定子進程和父進程誰先執(zhí)行,是隨機的,所以每次執(zhí)行的結果可能會不一樣的,父進程與子進程爭奪CPU資源。所以最終的輸出結果是acbc或者是bcac。問題:觀察屏幕上的顯示結果,并分析多次運行為什么會出現(xiàn)不同的結果。答:fork出來的進程不能確定子進程和父進程誰先執(zhí)行,是隨機的,所以每次執(zhí)行的結果可能會不一樣的,父進程與子進程爭奪CPU資源。實驗2-2結果分析:從main()函數(shù)開始,父進程創(chuàng)建子進程,首先判斷子進程是否創(chuàng)建成功,如果pid<0則創(chuàng)建進程失敗,當pid=0時,運行子進程,輸出系統(tǒng)當前目錄。父進程將會一直等待子進程信號,只有當子進程釋放信號,父進程輸出“ChildComplete”。問題:觀察該程序在屏幕上的顯示結果,并分析實驗結果。答:分析:屏幕上出現(xiàn)的是當前目錄的列表,以及子進程結束打印輸出的子進程complete,首先該程序創(chuàng)建一個子進程然后,但是fork()是一次調(diào)用返回兩個參數(shù),在父進程中返回的是創(chuàng)建子進程的ID,在子進程中返回的是0,故會同時出現(xiàn)一起存在的結果小結與心得體會本實驗在實驗一的基礎上將創(chuàng)建進程實驗到了Linux系統(tǒng)上,實驗是有兩個塊組成,創(chuàng)建進程和子進程執(zhí)行新任務構成,本實驗最重要的一個函數(shù)就是fork()函數(shù),就是在fork的時候調(diào)用一次,返回兩個參數(shù),這也是對于這個實驗的基本理解,在Linux中利用fork建立一個子進程,父進程繼續(xù)運行,子進程在同樣的位置執(zhí)行同樣的程序。對于子進程,fork()返回0,出錯時返回-1,對于父進程,fork()返回子進程的pid,while((x=fork())==-1)這句話是用來判斷子進程是否能創(chuàng)建成功,而且當x=0時運行子進程,當x>0時父進程執(zhí)行,而x<0時,則進程創(chuàng)建不成功,通過代碼輸出相應的字符去確定父子進程的先后執(zhí)行順序,也同時可以發(fā)現(xiàn)子父進程會爭奪cpu資源形成兩中不同的結果,說明進程的執(zhí)行是隨機的關鍵看是否獲得資源。通過本實驗初步認識了Linux系統(tǒng)下如何創(chuàng)建進程以及進程是如何執(zhí)行的,以及對于fork函數(shù)的深刻理解,也讓我感受到了Linux系統(tǒng)的簡約,原始點但也能說是有趣,發(fā)現(xiàn)這個開源的系統(tǒng)比想象的要更加有趣,以及在現(xiàn)在主流的操作系統(tǒng)中我也認為它能很好的完成各種功能的實現(xiàn),只不過相對比較麻煩一點罷了,但是對于程序員來說這樣才能更加深入的了解底層的原理才能更好的提升自己的能力。實驗題目實驗三、Linux進程間通信實驗目的Linux系統(tǒng)的進程通信機構(IPC)允許在任意進程間大批量地交換數(shù)據(jù),通過本實驗,理解熟悉Linux支持的消息通信機制。實驗內(nèi)容背景知識UINX/Linux系統(tǒng)把信號量、消息隊列和共享資源統(tǒng)稱為進程間通信資源(IPCresource)。提供給用戶的IPC資源是通過一組系統(tǒng)調(diào)用實現(xiàn)的。這組系統(tǒng)調(diào)用為用戶態(tài)進程提供了以下三種服務:用信號量對進程要訪問的臨界資源進行保護。用消息隊列在進程間以異步方式發(fā)送消息。用一塊預留出的內(nèi)存區(qū)域供進程之間交換數(shù)據(jù)。在Linux中創(chuàng)建子進程要使用fork()函數(shù),執(zhí)行新的命令要使用exec()系列函數(shù),等待子進程結束使用wait()函數(shù),結束終止進程使用exit()函數(shù)。fork()原型如下:pid_tfork(void);fork建立一個子進程,父進程繼續(xù)運行,子進程在同樣的位置執(zhí)行同樣的程序。對于父進程,fork()返回子進程的pid,對于子進程,fork()返回0。出錯時返回-1。模塊介紹主函數(shù)、SERVER函數(shù)、CLIENT函數(shù)實驗步驟用一個程序作為“引子”,先后fork()兩個子進程SERVER和CLIENT,進行通信。SERVER端建立一個key為75的消息隊列,等待其他進程發(fā)來的消息。當遇到類型為1的消息,則作為結束信號,取消該隊列,并退出SERVER。SERVER每接收到一個消息后顯示一句“(server)received”。CLIENT端使用key為75的消息隊列,先后發(fā)送類型從10到1的消息,然后退出。最后的一個消息,即是SERVER端需要的結束信號。CLIENT每發(fā)送一條消息后顯示一句“(client)sent”。父進程在SERVER和CLIENT均退出后結束。數(shù)據(jù)結構#defineMSGKEY75structmsgform{longmtype; charmtext[1030];}msg;intmsgqid,i;程序流程圖關鍵代碼voidCLIENT(){inti;msgqid=msgget(MSGKEY,0777);for(i=10;i>=1;i--){msg.mtype=i; printf("(client)sent\n"); msgsnd(msgqid,&msg,1024,0);}exit(0);}voidSERVER(){msgqid=msgget(MSGKEY,0777|IPC_CREAT);do{msgrcv(msgqid,&msg,1030,0,0); printf("(Server)recieved\n");}while(msg.mtype!=1);msgctl(msgqid,IPC_RMID,0);exit(0);}voidmain(){while((i=fork())==-1);if(!i)SERVER();while((i=fork())==-1);if(!i)CLIENT();wait(0);wait(0);}實驗結果與分析實驗3-1結果分析:這個程序從主函數(shù)開始,然后通過fork()函數(shù)創(chuàng)建兩個子進程SERVER和CLIENT,用來進行通信。在client函數(shù)中創(chuàng)建75序列,打開0777序列標識符然后后續(xù)傳遞給server函數(shù)進行匹配,然后設定msg.mtype=i就是讓后面server函數(shù)唯一接收client傳過來的信息,for循環(huán)10次,傳遞10次信息,通過msgsnd(msgqid,&msg,1024,0)來傳遞信息。問題:從理論上說,上述程序應當是每當client發(fā)送一條消息后,server接收該消息,client再發(fā)送下一條,也即是應該交替出現(xiàn)(client)sent和(server)received,但實際結果大多不是這樣,會出現(xiàn)幾個(client)sent連續(xù)后再幾個(server)received,請分析原因。答:message的傳送和控制并不保證完全同步,當一個程序不再激活狀態(tài)的時候,它完全可能繼續(xù)睡眠,造成上面現(xiàn)象,在多次sendmessage后才receivemessage.這一點有助于理解消息轉送的實現(xiàn)機理.小結與心得體會本實驗是對于熟悉Linux支持的消息通信機制,在Linux系統(tǒng)的進程通信機構(IPC)允許在任意進程間大批量地交換數(shù)據(jù),通過本實驗讓我熟悉了解了通信的傳送與接收的機制,在message傳送與接收的過程中,其實在傳送與接收的過程中并不是完全同步的,在多次多次sendmessage后才receivemessage,通過實驗,體會到了Linux系統(tǒng)在這方面的功能,也很好的了解了本實驗所要我們學習的本質!這也可以看看現(xiàn)在生活中的通信機制,當然不是進程之間,但十分相似與相近,在我們使用qq或者微信的時候,我們也等同于一個發(fā)送機制和一個接收機制,所以想象一下我們現(xiàn)在如此發(fā)達的通信的時代,研究人員是如何去減少這個延時,當我們網(wǎng)絡信號不好時,延時就會很大,也很難同步。在本實驗中我們所使用的是操作系統(tǒng)中的消息隊列這一進程通信方法,我不僅深入了解本實驗所用的消息隊列的方式,還了解到還有管道、信號量、信號、共享內(nèi)存、套接字等這些方式的特點,了解過后也對linux進程通信方式有了全面的了解,讓我感受到通信的多樣化與奇特!實驗題目實驗四、Windows的互斥與同步二、實驗目的回顧操作系統(tǒng)進程、線程的有關概念,加深對Windows線程的理解。了解互斥體對象,利用互斥與同步操作編寫生產(chǎn)者-消費者問題的并發(fā)程序,加深對P(即semWait)、V(即semSignal)原語以及利用P、V原語進行進程間同步與互斥操作的理解。實驗內(nèi)容背景知識信號量:信號量是一個與隊列有關的整型變量??梢猿跏蓟煞秦摂?shù);semWait操作使信號量減1。若值為負數(shù),則執(zhí)行semWait的進程阻塞,否則繼續(xù)執(zhí)行;semSignal操作使信號量加1。若值小于或等于0,則被semWait操作阻塞的進程被解除阻塞。模塊介紹生產(chǎn)者:Produce()、Append()和消費者:Take()、Consume()實驗步驟生產(chǎn)者消費者問題創(chuàng)建一個工程,用清單4-1中的程序,編譯成可執(zhí)行文件。在命令窗口運行步驟1中生成的可執(zhí)行文件,列出運行結果。仔細閱讀源程序,找出創(chuàng)建線程的WINDOWSAPI函數(shù)修改清單4-1中的程序,調(diào)整生產(chǎn)者線程和消費者線程的個數(shù),使得消費者數(shù)目大與生產(chǎn)者,觀察察運行結果。修改信號量EmptySemaphore的初始化方法,觀察結果有何不同。根據(jù)步驟4的結果,并查看MSDN。數(shù)據(jù)結構constunsignedshortSIZE_OF_BUFFER=2;//緩沖區(qū)長度unsignedshortProductID=0;//產(chǎn)品號unsignedshortConsumeID=0;//將被消耗的產(chǎn)品號unsignedshortin=0;//產(chǎn)品進緩沖區(qū)時的緩沖區(qū)下標unsignedshortout=0;//產(chǎn)品出緩沖區(qū)時的緩沖區(qū)下標intbuffer[SIZE_OF_BUFFER];//緩沖區(qū)是個循環(huán)隊列boolp_ccontinue=true;//控制程序結束HANDLEMutex;//用于線程間的互斥HANDLEFullSemaphore;//當緩沖區(qū)滿時迫使生產(chǎn)者等待HANDLEEmptySemaphore;//當緩沖區(qū)空時迫使消費者等待DWORDWINAPIProducer(LPVOID);//生產(chǎn)者線程DWORDWINAPIConsumer(LPVOID);//消費者線程程序流程圖關鍵代碼DWORDWINAPIProducer(LPVOIDlpPara)//生產(chǎn)者{while(p_ccontinue){WaitForSingleObject(EmptySemaphore,INFINITE);//p(empty);WaitForSingleObject(Mutex,INFINITE); //p(mutex);Produce();Append();Sleep(1500);ReleaseMutex(Mutex); //V(mutex);ReleaseSemaphore(FullSemaphore,1,NULL); //V(full); }return0;}DWORDWINAPIConsumer(LPVOIDlpPara)//消費者{ while(p_ccontinue){WaitForSingleObject(FullSemaphore,INFINITE);//P(full);WaitForSingleObject(Mutex,INFINITE); //P(mutex);Take();Consume();Sleep(1500);ReleaseMutex(Mutex); //V(mutex);ReleaseSemaphore(EmptySemaphore,1,NULL); //V(empty); }return0;}實驗結果與分析實驗4-1結果分析:修改后代碼清單4-1后,從main()函數(shù)開始,首先創(chuàng)建了生產(chǎn)者-消費者問題中應用到的互斥信號和同步信號以及其他基礎定義,創(chuàng)建消費者生產(chǎn)者線程;最初生產(chǎn)者滿足條件生產(chǎn)產(chǎn)品,所以先執(zhí)行生產(chǎn)者,然后當資源有產(chǎn)品時,會執(zhí)行消費者,生產(chǎn)者和消費者在代碼運行過程中出現(xiàn)是隨機的,當生產(chǎn)者多于消費者時,生產(chǎn)速度快,生產(chǎn)者經(jīng)常等待消費者;反之,消費者經(jīng)常等待;若緩沖區(qū)為空,則必定是生產(chǎn)者運行,緩沖區(qū)為滿,則消費者運行,生產(chǎn)者等待,而對于結果的表示,則是調(diào)用Append()和Consume()中的循環(huán)輸出。問題:線程的第一個執(zhí)行函數(shù)是什么(從哪里開始執(zhí)行)?它位于創(chuàng)建線程的API函數(shù)的第幾個參數(shù)中?答:生產(chǎn)者第一個執(zhí)行的函數(shù)是Producer(),消費者第一個執(zhí)行的函數(shù)是Consumer(),位于創(chuàng)建線程API的第3個函數(shù)。實驗4-2結果分析:當生產(chǎn)者多余消費者時候,生產(chǎn)者生產(chǎn)多個的時候消費者才會去消費。當生產(chǎn)者少于消費者時,生產(chǎn)者基本每生產(chǎn)一個,消費者就消費一個。問題:觀察結果有何不同,從中你可以得出什么結論?答:當生產(chǎn)者個數(shù)多于消費者個數(shù)時生產(chǎn)速度快,生產(chǎn)者經(jīng)常等待消費者對產(chǎn)品進行消費;反之,消費者經(jīng)常等待生產(chǎn)者生產(chǎn)。實驗4-3結果分析:將資源EmptySemaphore的初始值設置為0,也就是一開始兩個資源都不能獲取,導致無論是生產(chǎn)者還是消費者的P操作都不無法取到資源,只能一直等待,所以窗口不輸出任何東西,表示的含義就是生產(chǎn)者和消費者都在等待EmptySemphore資源的釋放。小結與心得體會通過本實驗深入了解互斥體對象,利用互斥與同步操作編寫生產(chǎn)者-消費者問題的并發(fā)程序,加深對P(即semWait)、V(即semSignal)原語以及利用P、V原語進行進程間同步與互斥操作的理解,還回顧了顧操作系統(tǒng)進程、線程的有關概念,加深對Windows線程的理解,在本實驗中,有意思的就是可以通過改變生產(chǎn)者和消費者的數(shù)量大小來觀察在進程運行的時候,生產(chǎn)者和消費者的狀態(tài),當消費者大于個數(shù)多于消費者個數(shù)時生產(chǎn)速度快,生產(chǎn)者經(jīng)常等待消費者對產(chǎn)品進行消費;反之,消費者經(jīng)常等待生產(chǎn)者生產(chǎn)。這也和老師上課講的理論知識遙相呼應,也讓我更加加深了對于生產(chǎn)者消費者的問題的理解,接著通過設置資源EmptySemaphore的初始值設置為0,使其兩個資源不能進行獲取,導致無論消費者還是生產(chǎn)者都是在不停的等待,導致界面的不顯示,所以在進行實驗的時候通過改變一個小小的值就可以改變實驗結果,也讓我體會到底層語言的艱辛,也感覺到了寫代碼時候要及其注意參數(shù)的傳遞,因為可能由于參數(shù)的傳遞,或者對于資源的賦值就可以改變實驗結果,達不到想要的效果,所以我們再檢查錯誤時候要仔細檢查這方面的錯誤,通過本實驗收獲很多,感觸頗深!實驗題目實驗六、銀行家算法的模擬與實現(xiàn)實驗目的進一步理解進程的并發(fā)執(zhí)行。加強對進程死鎖的理解,理解安全狀態(tài)與不安全狀態(tài)的概念。掌握使用銀行家算法避免死鎖問題??傮w設計背景知識 死鎖:多個進程在執(zhí)行過程中,因為競爭資源會造成相互等待的局面。如果沒有外力作用,這些進程將永遠無法向前推進。此時稱系統(tǒng)處于死鎖狀態(tài)或者系統(tǒng)產(chǎn)生了死鎖。 安全序列:系統(tǒng)按某種順序并發(fā)進程,并使它們都能達到獲得最大資源而順序完成的序列為安全序列。 安全狀態(tài):能找到安全序列的狀態(tài)稱為安全狀態(tài),安全狀態(tài)不會導致死鎖。 不安全狀態(tài):在當前狀態(tài)下不存在安全序列,則系統(tǒng)處于不安全狀態(tài)。 銀行家算法:銀行家算法顧名思義是來源于銀行的借貸業(yè)務,一定數(shù)量的本金要滿足多個客戶的借貸周轉,為了防止銀行家資金無法周轉而倒閉,對每一筆貸款,必須考察其是否能限期歸還。當一進程提出資源申請時,銀行家算法執(zhí)行下列步驟以決定是否向其分配資源:檢查該進程所需要的資源是否已超過它所宣布的最大值。檢查系統(tǒng)當前是否有足夠資源滿足該進程的請求。系統(tǒng)試探著將資源分配給該進程,得到一個新狀態(tài)。執(zhí)行安全性算法,若該新狀態(tài)是安全的,則分配完成;若新狀態(tài)是不安全的,則恢復原狀態(tài),阻塞該進程。模塊介紹主函數(shù)運行模塊銀行家算法模塊檢查資源分配安全模塊輸出資源分配模塊設計步驟初始化時讓系統(tǒng)擁有一定的資源;用鍵盤輸入的方式允許進程動態(tài)申請資源;如果試探分配后系統(tǒng)處于安全狀態(tài),則修改系統(tǒng)的資源分配情況,正式分配資源;如果試探分配后系統(tǒng)處于不安全狀態(tài),則提示不能滿足請求,恢復原狀態(tài)并阻塞該進程。詳細設計數(shù)據(jù)結構資源總量向量Resource,m維,表示m種資源的總量??捎觅Y源向量Available,m維,表示未分配的各種可用資源數(shù)量。需求矩陣Claim,n*m矩陣,表示n個進程對m類資源的最大需求。分配矩陣Allocation,n*m矩陣,表示n個進程已分配的各種資源數(shù)。程序流程圖關鍵代碼intchkerr(ints)//函數(shù)chkerr,檢查是否安全{while(1){inti; intflag1=0; for(i=0;i<M;){ intsum=0;intk; for(k=0;k<M;k++){sum+=FINISH[k];}if(sum==M){ intij;printf("存在安全序列:["); for(ij=0;ij<M;ij++){ printf("p%d",array[ij]);} printf("]\n"); printf("【經(jīng)安全性檢查,系統(tǒng)安全,本次分配成功?!縗n\n"); return1; }if(FINISH[i]!=1){ flag1=0; for(intj=0;j<N;j++){//資源檢查 if(NEED[i][j]>WORK[j]){//進程i所需要的資源j能否被滿足 flag1=1;break;}}}//有不滿足的,就退出 if(flag1==0&&FINISH[i]!=1){//表示i進程沒執(zhí)行,且可以執(zhí)行 intj; FINISH[i]=1;//i號進程,可以執(zhí)行 printf("進程p%d執(zhí)行\(zhòng)n",i);printf("系統(tǒng)當前可用資源:"); for(j=0;j<N;j++) {WORK[j]+=ALLOCATION[i][j];//各分配的資源回收 printf("%d",WORK[j]); } printf("\n"); array[cnt++]=i; i=0;}else{i++;}}//不能執(zhí)行判斷下一個進程實驗結果與分析實驗結果:首先剛進去的界面進行資源展示的界面當輸入不合理時:分配失敗時:分配成功時:實驗分析:本實驗由幾個模塊組成,先是對于進程所需資源量和剩余資源量的計算,然后調(diào)用顯示函數(shù),將所有的資源數(shù)量以及進程的各種數(shù)量顯示出來,接著就是銀行家算法的主體,通過用戶輸入的進程分配第一個資源,接著由程序自行判斷,用銀行家算法變成資源預分配狀態(tài),接著運用安全檢測函數(shù)檢測與分配的安全性,如果安全責則輸出安全序列,分配成功,否則資源請求不合理再重新調(diào)配資源。小結與心得體會通過本實驗加深了我對死鎖避免銀行家算法的理解,死鎖避免其關鍵首先在于對于請求資源不能大于剩余資源的數(shù)量,也就是用戶剛開始輸入判斷的那步,還有就是要時刻檢查資源是否足夠還有系統(tǒng)嘗試著分配資源給進程然后得到新的安全序列,不安全則恢復,這也是銀行家算法的核心。在本實驗中還加深了我對于進程死鎖的理解,理解安全狀態(tài)與不安全狀態(tài)的概念,進程死鎖的條件是互斥、占有且等待、不可搶占、循環(huán)等待,這也是在避免死鎖時的關鍵,可以通過對于任一條件的不滿足破壞死鎖,但是銀行家算法相比與其他,代價較小,當進程分配的為死鎖序列時,程序將會進行回滾,恢復原來的狀態(tài),使系統(tǒng)不會出現(xiàn)死鎖狀態(tài)。在做本實驗之前,在學習銀行家算法時,原本是有一些些不明白,在通過本實驗之后,茅塞頓開,感覺十分奇妙,是死鎖避免安全性檢查的奇特,也讓我對操作系統(tǒng)的興趣又加深了一步,也希望將來能夠學習到更多更深的知識去豐富自己,加強自己。實驗題目實驗七、磁盤調(diào)度算法的模擬與實現(xiàn)實驗目的了解磁盤結構以及磁盤上數(shù)據(jù)的組織方式。掌握磁盤訪問時間的計算方式。掌握常用磁盤調(diào)度算法及其相關特性??傮w設計背景知識磁盤調(diào)度算法:磁盤調(diào)度的目的是要盡可能降低磁盤的尋道時間,以提高磁盤I/O系的性能。先進先出算法FIFO:按訪問請求到達的先后次序進行調(diào)度。最短服務時間優(yōu)先算法SSTF:優(yōu)先選擇使磁頭臂從當前位置開始移動最少的磁盤I/O請求進行調(diào)度。SCAN(電梯算法):要求磁頭臂先沿一個方向移動,并在途中滿足所有未完成的 請求,直到它到達這個方向上的最后一個磁道,或者在這個方向上沒有別的請求為止,后一種改進有時候稱作LOOK策略。然后倒轉服務方向,沿相反方向掃描,同樣按順序完成所有請求。C-SCAN(循環(huán)掃描)算法:在磁盤調(diào)度時,把掃描限定在一個方向,當沿某個方 向訪問到最后一個磁道時,磁頭臂返回到磁盤的另一端,并再次開始掃描。磁盤數(shù)據(jù)的組織:磁盤上每一條物理記錄都有唯一的地址,該地址包括三個部分:磁頭號(盤面號)、柱面號(磁道號)和扇區(qū)號。給定這三個量就可以唯一地確定一個地址。磁盤訪問時間的計算方式:磁盤在工作時以恒定的速率旋轉。為保證讀或寫,磁頭必須移動到所要求的磁道上,當所要求的扇區(qū)的開始位置旋轉到磁頭下時,開始讀或寫數(shù)據(jù)。對磁盤的訪問時間包括:尋道時間、旋轉延遲時間和傳輸時間。模塊介紹主函數(shù)模塊先進先出算法FIFO模塊最短服務時間優(yōu)先算法SSTF模塊SCAN(循環(huán)掃描)算法模塊C-SCAN(循環(huán)掃描)算法模塊設計步驟首先對于main函數(shù)的總體設計,采用用戶輸入磁道號數(shù)組與算法編號,然后調(diào)用相應算法函數(shù)先進先出算法FIFO模塊的設計最短服務時間優(yōu)先算法SSTF模塊的設計SCAN(循環(huán)掃描)算法模塊的設計C-SCAN(循環(huán)掃描)算法模塊的設計詳細設計數(shù)據(jù)結構#definemaxsize1000//定義最大數(shù)組域voidsort(int*a,intleft,intright)//二分法排序voidFIFO(intarray[],intm)//先進先出調(diào)度算法voidSSTF(intarray[],intm)//最短服務時間優(yōu)先算法voidSCAN(intarray[],intm)//掃描算法,采用look策略voidCSCAN(intarray[],intm)//循環(huán)掃描算法,采用look策略程序流程圖3.關鍵代碼voidsort(int*a,intleft,intright)//二分法排序{if(left>=right)/*如果左邊索引大于或者等于右邊的索引就代表已經(jīng)整理完成一個組了*/{return;}inti=left;intj=right;intkey=a[left];while(i<j)/*控制在當組內(nèi)尋找一遍*/{while(i<j&&key<=a[j])//找到從右邊開始第一個大于key的值 /*而尋找結束的條件就是找到一個小于或者大于key的數(shù)(大于或小于取決于你想升序還是降序)2、沒有符合條件1的,并且i與j的大小沒有反轉*/{ j--;}/*向前尋找*/a[i]=a[j];/*找到一個這樣的數(shù)后就把它賦給前面的被拿走的i的值(如果第一次循環(huán)且key是a[left],那么就是給key)*/while(i<j&&key>=a[i])/*這是i在當組內(nèi)向前尋找,同上,不過注意與key的大小關系停止循環(huán)和上面相反,因為排序思想是把數(shù)往兩邊扔,所以左右兩邊的數(shù)大小與key的關系相反*/{ i++; }a[j]=a[i];} a[i]=key; /*當在當組內(nèi)找完一遍以后就把中間數(shù)key回歸*/ sort(a,left,i-1);/*最后用同樣的方式對分出來的左邊的小組進行同上的做法*/ sort(a,i+1,right);/*用同樣的方式對分出來的右邊的小組進行同上的做法*/ /*當然最后可能會出現(xiàn)很多分左右,直到每一組的i=j為止*/}實驗結果與分析實驗結果:先進先出算法(FIFO)最短服務時間優(yōu)先算法(SSTF)掃描算法(SCAN)(LOOK策略)循環(huán)掃描算法(C-SCAN)(LOOK策略)實驗分析:先來先服務的優(yōu)點為簡單與公平,缺點就是平均尋道時間距離大,效率不高,磁壁粘著,適用于磁盤I/O較少的場合;最短尋道時間優(yōu)先算法性能比"先來先服務"好,能保證平均尋道時間最短,但是可能出現(xiàn)"饑餓"現(xiàn)象,
磁壁粘著;掃描算法尋道性能較好,可避免"饑餓"現(xiàn)象;既考慮了距離,同時又考慮了方向,但是卻不利于遠離磁頭一端的訪問請求,
磁壁粘著;循環(huán)掃描算法則消除了對兩端磁道請求的不公平。小結與心得體會通過本次實驗讓我充分了解了掌握常用磁盤調(diào)度算法及其相關特性,在本實驗我們模擬的是磁盤調(diào)度的模擬和實現(xiàn),充分了解其各種調(diào)度算法的原理以及對于尋道數(shù)量以及平均尋道長度的理解,在設計算法時候,要注意的就是要掌握各算法特性以及它調(diào)度的規(guī)律,我們在設計算法時,還要注意代碼代碼的重復利用性,就是可以單獨提出一個重復利用到的函數(shù),比如掃描算法都是運用了look策略,我們就使用了一個sort二分查找的函數(shù)供他們調(diào)用,減少了代碼的耦合性,還是代碼不顯得冗余、易懂。然后在設計算法時遇到的困難就是在設計時要運用許多的for循環(huán)去累加數(shù),比如累加尋道數(shù)量的累加,容易搞混淆,要及其注意,然后還有對于其他來說就是sort函數(shù)的編寫,通過各種學習與請教,讓我搞懂以及不斷測試后,終于將程序功能變得十分完善,十分完美。通過這次的學習,讓我感受到了計算機磁盤調(diào)度的奇妙之處,在不同場合結果其實并不相同,分為不同的場合,各種磁盤調(diào)度算法都不一樣,也讓我感受到,人類真正實現(xiàn)智能化,還需要我們這一代的努力與奮斗,不斷突破自我,深入學習,才能使操作系統(tǒng)的未來更上一層樓,我也愿意在這方面貢獻我的綿薄之力!實驗題目實驗九、基于信號量機制的并發(fā)程序設計實驗目的回顧操作系統(tǒng)進程、線程的有關概念,針對經(jīng)典的同步、互斥、死鎖與饑餓問題進行并發(fā)程序設計與實現(xiàn)。理解Linux支持的信息量機制,利用IPC的信號量系統(tǒng)調(diào)用編程實現(xiàn)哲學家進餐問題??傮w設計背景知識哲學家進餐問題描述有五個哲學家,他們的生活方式是交替地進行思考和進餐,哲學家們共用一張圓桌,分別坐在周圍的五張椅子上,在圓桌上有五個碗和五支筷子,平時哲學家進行思考,饑餓時便試圖取其左、右最靠近他的筷子,只有在他拿到兩支筷子時才能進餐,該哲學家進餐完畢后,放下左右兩只筷子又繼續(xù)思考。約束條件:只有拿到兩只筷子時,哲學家才能吃飯。如果筷子已被別人拿走,則必須等別人吃完之后才能拿到筷子。任一哲學家在自己未拿到兩只筷子吃完飯前,不會放下手中已經(jīng)拿到的筷子模塊介紹wait_for_2fork()模塊(對兩個筷子進行p操作)free_2fork()模塊(對筷子進行V操作)philosephere()模塊(哲學家模塊)Main()主函數(shù)模塊設計步驟分析實驗要求,找到實驗解決辦法,確定數(shù)據(jù)結構分析然后編寫主函數(shù)模塊,定義5個信號量都為1,創(chuàng)建五個進程編寫philosephere()模塊(哲學家模塊),對于進程進行PV操作編寫P操作函數(shù)模塊編寫V操作函數(shù)模塊運行測試、分析結果詳細設計數(shù)據(jù)結構#defineERR_EXIT(m)do{perror(m);exit(EXIT_FAILURE);}while(0)#defineDELAY(rand()%5+1)intsemid;//信號量IDunionsemun{ intval; /*ValueforSETVAL*/ structsemid_ds*buf; /*BufferforIPC_STAT,IPC_SET*/ unsignedshort*array; /*ArrayforGETALL,SETALL*/ structseminfo*__buf; /*BufferforIPC_INFO(Linux-specific)*/};程序流程圖關鍵代碼voidwait_for_2fork(intno)//P操作{ intleft=no;intright=(no+1)%5;//拿右邊的筷子structsembufbuf[2]={{left,-1,0},{right,-1,0}};//拿起筷子,因此第left,right信號量減一semop(semid,buf,2);//P操作,若果能同時拿起兩個筷子,就不用等待}voidfree_2fork(intno)//V操作{ intleft=no;intright=(no+1)%5;structsembufbuf[2]={{left,1,0},{right,1,0}};//放下筷子,因此第left,right信號量加一semop(semid,buf,2);//V操作,同時放下兩只筷子}intphilosephere(intno)//哲學家算法{srand(getpid());for(;;){printf("%disthinking\n",no);sleep(DELAY);printf("%dishungry\n",no);wait_for_2fork(no);printf("%diseating\n",no);sleep(DELAY);free_2fork(no);}}intmain(intargc,char*argv[]){unionsemunsu;su.val=1;semid=semget(IPC_PRIVATE,5,IPC_CREAT|0666);//因為是父子進程通信,可以設置為IPC_PRIVATE,五個人,因此管理五個信號量if(semid==-1)ERR_EXIT("semget");for(inti=0;i<5;i++)semctl(semid,i,SETVAL,su);//將5個信號量分別初始化為1intno=0;inti=0;pid_tpid;for(i=1;i<5;i++){pid=fork(); //產(chǎn)生5個進程if(pid==-1)ERR_EXIT("fork");if(pid==0){no=i;break;//必須break,否則子進程會創(chuàng)建出新的進程}}//printf("no=%d\n",no);philosephere(no);return0;}實驗結果與分析實驗結果:........分析:實驗未出現(xiàn)死鎖現(xiàn)象,進程一直在重復的思考、就餐。然后程序沒有運行卡著,即沒有發(fā)生死鎖現(xiàn)象,從中也可以發(fā)現(xiàn)同時最多只能有兩個哲學家一起用餐,也不會出現(xiàn)相鄰哲學家一起用餐的情況。小結與心得體會通過本次實驗首先是對于哲學家就餐問題有了更深的了解,按照實驗要求通過PV操作來解決哲學家就餐問題,這也使我回顧了操作系統(tǒng)進程、線程的有關概念,針對經(jīng)典的同步、互斥、死鎖與饑餓問題進行并發(fā)程序設計與實現(xiàn),在運用PV操作解決哲學家問題的同時,我也發(fā)現(xiàn)了另外幾種可以很好解決哲學家就餐問題的方法,比如允許最多4個哲學家同時坐在桌子上或者只有一個哲學家的兩根筷子都可用時,他才能拿起它們(他必須在臨界區(qū)內(nèi)拿起兩根筷子)?;蛘呤褂梅菍ΨQ解決方案。即單號的哲學家先拿起左邊的筷子,接著右邊的筷子;而雙號的哲學家先拿起右邊的筷子,接著左邊的筷子。在設計本實驗時,主要就是PV操作的運用,在運用PV操作時就是對于semop函數(shù)的操作,先是對于信號量的加一或者減一,然后調(diào)用semop函數(shù)進行PV操作,因此本實驗的關鍵就是對于信號量系統(tǒng)調(diào)用編程實現(xiàn)哲學家進餐問題,也讓我深刻理解了Linux支持的信息量機制,我也從中體會到操作系統(tǒng)的奇妙之處,加深了我對于操作系統(tǒng)的學習以及理解,我從中也受益匪淺。實驗題目實驗十、簡單shell命令行解釋器的設計與實現(xiàn)實驗目的本實驗主要目的在于進一步學會如何在Linux系統(tǒng)下使用進程相關的系統(tǒng)調(diào)用,了解shell工作的基本原理,自己動手為Linux操作系統(tǒng)設計一個簡單的命令接口??傮w設計背景知識常見的shell內(nèi)部命令如下:cd<目錄>更改當前的工作目錄到另一個<目錄>。如果<目錄>未指定,輸出當前工作目錄如果<目錄>不存在,應當有適當?shù)腻e誤信息提示。這個命令應該也能改變PWD的環(huán)境變量environ列出所有環(huán)境變量字符串的設置(類似于Linux系統(tǒng)下的env命令)echo<內(nèi)容>顯示echo后的內(nèi)容且換行help簡短概要的輸出你的shell的使用方法和基本功能。jobs輸出shell當前的一系列子進程,必須提供子進程的命名和PID號。quit,exit,bye退出shell。提示:shell的主體就是反復下面的循環(huán)過程while(1){接收用戶輸入的命令行;解析命令行;if(用戶命令為內(nèi)部命令)直接處理;elseif(用戶命令為外部命令)創(chuàng)建子進程執(zhí)行命令;else提示錯誤的命令;}模塊介紹一個main函數(shù)模塊包含了判斷與響應的操作設計步驟分析實驗要求,確定好所要實現(xiàn)的shell內(nèi)部命令,確定數(shù)據(jù)結構將所確定的shell命令行進行分類,按照首字母來分類在細分shell命令,編寫shell命令詳細操作測試程序,分析結果 詳細設計數(shù)據(jù)結構charcmd[2100]; //用來存放用戶的輸入命令intlen=strlen(cmd)//用來獲取用戶命令行長度charcata[100]; //用來將cmd值傳遞賦值程序流程圖關鍵代碼intmain(){charcmd[2100];while(1){printf("\n--------------------------------------------------\n"); printf("shell命令行解釋器"); printf("\n--------------------------------------------------\n\n");printf("請輸入你的操作:");scanf("%s",cmd);Intlen=strlen(cmd),i;if(cmd[0]=='e'&&cmd[1]=='c')//echo{intflag=0;for(i=5;i<len-1;i++){if(cmd[i]!='')flag=1;//hif(flag){putchar(cmd[i]);}} if(flag){putchar('\n');}elseif(cmd[0]=='q'||cmd[1]=='x'||cmd[0]=='b')//quit,exit,bye {printf("Bye\n"); return0;}elseif(cmd[0]=='h'){ //helpprintf("echo<content>\tprintalinecontent\n");printf("quit,exit,bye\tendproduce\n");printf("cd<catalog>\techocatalog\n");printf("jobs\techoprocessnameandpid...\n");printf("environ\techoenvironmentvariable\n");}els
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025-2030產(chǎn)學研合作創(chuàng)新行業(yè)市場深度分析及競爭格局與投資價值研究報告
- 2025-2030中國魚蛋白行業(yè)市場現(xiàn)狀供需分析及投資評估規(guī)劃分析研究報告
- 冰山巧克力采購合同樣本
- 2025-2030中國馬爾基波行業(yè)市場現(xiàn)狀供需分析及投資評估規(guī)劃分析研究報告
- 2025-2030中國飼料行業(yè)市場發(fā)展分析及發(fā)展前景與投資研究報告
- 2025-2030中國鞋業(yè)連鎖市場占有率調(diào)查及投資效益分析研究報告
- 農(nóng)村平房加蓋新房合同標準文本
- 力工合同標準文本
- 養(yǎng)生店入股合同樣本
- 藥物分析方法考查試題及答案
- 《綠色建筑概論》整套教學課件
- 證據(jù)法學李浩課件 第五章
- 圖書館建筑設計規(guī)范講解課件
- 考研考博-英語-北京建筑大學考試押題卷含答案詳解3
- 愛蓮說-王崧舟
- 光伏支架安裝施工協(xié)議
- 保定市縣級地圖PPT可編輯矢量行政區(qū)劃(河北省)
- 第四章通道內(nèi)非耦合層流的
- 供水管網(wǎng)施工組織設計
- 異面直線所成的角與求法
- 信息安全風險評估培訓(課堂PPT)
評論
0/150
提交評論