




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
2024年3月28日UNIX_Linux操作系統(tǒng)內(nèi)核結(jié)構(gòu)電子科技大學(xué)信軟件學(xué)院第七章進程控制控制進程上下文的系統(tǒng)調(diào)用包括三類:1、與存儲相關(guān)的forkexecbrk2、與同步相關(guān)的exitwaitsignalkill3、其他類別setpgrpsetuit7.1創(chuàng)立進程forkpid=fork()fork算法主要完成以下操作:1、檢查系統(tǒng)資源,為新進程在核心進程表proc表中分配一個空表項。2、為子進程分配一個唯一的進程標(biāo)識數(shù)PID,確認(rèn)用戶的總進程數(shù)沒有超限。3、拷貝父進程的上下文到子進程中,包括真正用戶標(biāo)識號、有效用戶標(biāo)識號、進程組號、調(diào)度優(yōu)先權(quán)等。初始化子進程中的相關(guān)參數(shù),如初始優(yōu)先權(quán)數(shù)、初始CPU使用時間、計時域等。調(diào)整文件的引用計數(shù)等。4、增加與該進程相關(guān)的file表項和活動inode表項的引用計數(shù)。5、對父進程返回子進程的進程號;對子進程那么返回0。算法fork輸入:無輸出:對父進程是子進程的PID對子進程是0{檢查可用的核心資源〔如內(nèi)外存空間、頁表等〕;取一個空閑的進程表項和唯一的PID號;檢查用戶沒有過多的運行進程;將子進程的狀態(tài)設(shè)為“創(chuàng)立”狀態(tài);將父進程的進程表項中的數(shù)據(jù)拷貝到子進程的進程表項中;當(dāng)前目錄的索引節(jié)點和改變的根目錄的引用計數(shù)加一;系統(tǒng)翻開文件表中相關(guān)表項的引用計數(shù)加一;在內(nèi)存中作父進程上下文的拷貝〔包括u區(qū)、正文、數(shù)據(jù)、堆棧〕;算法fork〔續(xù)〕在子進程的系統(tǒng)及上下文中壓入虛設(shè)的系統(tǒng)及上下文層/*虛設(shè)的上下文層中含有使子進程能夠識別自己的數(shù)據(jù),*并使子進程被調(diào)度時從這里開始*/if(正在執(zhí)行的進程是父進程){將子進程的狀態(tài)設(shè)置為“就緒”狀態(tài);return〔子進程的PID〕;/*從系統(tǒng)態(tài)到用戶態(tài)*/}else/*當(dāng)前正在執(zhí)行的進程是子進程*/{初始化u區(qū)的計時域;return〔0〕;/*從系統(tǒng)態(tài)返回到用戶態(tài)*/}}main(intargc,*argv[]){fdrd=open(argv[1],O_RDONLY);fdwt=create(argv[2],0666);fork();/*父子進程執(zhí)行下面相同的代碼*/rdwrt();exit(0);}rdwrt(){for(;;){if(read(fdrd,&c,1)!=1)return;write(fdwt,&c,1);}}實例1:雙進程文件拷貝
兩個進程共享讀指針和寫指針,但運行的結(jié)果并不能保證新文件中的內(nèi)容與老文件中的完全相同,這取決于父子兩個進程的調(diào)度順序。——多進程環(huán)境下的數(shù)據(jù)一致性問題。#include<string.h>charstring[]=“hello,world”;main(){intcount,i;intto_par[2],to_chil[2];/*到父、子進程的管道*/charbuf[256];pipe(to_par);pipe(to_chil);if(fork()==0){/*子進程從此處開始運行*/close(0);/*關(guān)閉老的標(biāo)準(zhǔn)輸入*/dup(to_chil[0]);/*把管道to_chil的讀指針復(fù)制到標(biāo)準(zhǔn)輸入*/close(1);/*關(guān)閉老的標(biāo)準(zhǔn)輸出*/dup(to_par[1]);/*把管道to_par的寫指針復(fù)制到標(biāo)準(zhǔn)輸出*/close(to_par[1]);/*關(guān)閉不再需要的管道描述符*/close(to_chil[0]);close(to_par[0]);close(to_chil[1]);for(;;){if((count=read(0,buf,sizeof(buf))==0)exit();write(1,buf,count);}/*父進程從此處開始運行*/close(1);/*重新設(shè)置父進程的標(biāo)準(zhǔn)輸入和輸出*/dup(to_chil[1]);close(0);dup(to_par[0]);close(to_chil[1]);close(to_par[0]);close(to_chil[0]);close(to_par[1]);for(i=0;i<15;i++){write(1,string,strlen(string));/*每次向to_chil管道寫11個字符*/read(0,buf,sizeof(buf));/*每次從to_par管道讀256個字符*/}}實例2:確保數(shù)據(jù)一致性的雙進程數(shù)據(jù)傳輸to_chilto_par[1]寫[0]讀[0]讀[1]寫子進程父進程子進程輸入子進程輸出父進程輸出父進程輸入在本例中,父子進程分別把自己的標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)輸出重新定向到to_chil和to_par管道中了,無論這兩個進程執(zhí)行相應(yīng)的系統(tǒng)調(diào)用的順序如何,兩個管道中的數(shù)據(jù)順序不會發(fā)生變化,因此兩個進程最終的讀寫結(jié)果不會改變。7.2軟中斷信號1、軟中斷信號的作用:
通知進程發(fā)生了異步事件需要處理。2、軟中斷信號的發(fā)出:
進程之間相互發(fā)送;
進程之內(nèi)給自己發(fā)送。3、發(fā)送軟中斷信號的方法:kill系統(tǒng)調(diào)用4、軟中斷信號的分類:〔1〕、與進程終止相關(guān)的軟中斷信號例如進程退出時〔2〕、與進程例外時間相關(guān)的軟中斷信號例如地址越界、寫只讀內(nèi)存區(qū)〔3〕、在系統(tǒng)調(diào)用期間遇到不可恢復(fù)的條件相關(guān)的軟中斷信號例如執(zhí)行exec而系統(tǒng)資源已用完〔4〕、在系統(tǒng)調(diào)用時遇到的非與此錯誤條件產(chǎn)生的軟中斷信號例如調(diào)用不存在的系統(tǒng)調(diào)用、向無讀進程的管道寫數(shù)據(jù)〔5〕、由在用戶態(tài)下運行的進程發(fā)出的軟中斷信號例如用kill向自己或其他進程發(fā)出的軟中斷信號〔6〕、與終端交互有關(guān)的軟中斷信號終端上按的break鍵或delete鍵等〔7〕、跟蹤進程執(zhí)行的軟中斷信號5、軟中斷信號的標(biāo)識
給一個進程發(fā)軟中斷信號時,核心在接收進程的核心進程控制表proc中,按所要接收的信號類型設(shè)置軟中斷信號域的某一位。
當(dāng)該接收進程睡眠在一個可被中斷的優(yōu)先級上時,核心就喚醒該進程。6、檢查軟中斷信號的時間
〔1〕當(dāng)一個進程即將從核心態(tài)返回到用戶態(tài)時;〔2〕當(dāng)一個進程即將進入或退出一個較低調(diào)度優(yōu)先級的睡眠狀態(tài)時。7、處理軟中斷信號的時刻僅當(dāng)進程從核心態(tài)返回用戶態(tài)時才處理軟中斷信號。由于軟中斷信號主要由應(yīng)用程序運行時發(fā)出,不是影響系統(tǒng)正常運行的緊急事件,故不在核心態(tài)下處理——當(dāng)進程在核心態(tài)下運行時,軟中斷信號并不立即起作用。算法issg/*檢查是否收到軟中斷信號*/輸入:無輸出:如果進程收到不忽略的軟中斷信號,那么為真;否那么為假{while(proc表項中收到的信號的域不為0){找出發(fā)送給進程的一個軟中斷信號號——是第幾號中斷;if(該信號是“子進程死”){if(忽略“子進程死”信號)釋放僵死的子進程的proc表項;elseif(捕俘“子進程死”信號)return(真);}elseif(不忽略信號)return(真);關(guān)掉proc表項中該信號域的〔要忽略的〕信號位}return(假)}8、軟中斷信號的處理進程在確認(rèn)收到軟中斷信號后,有三種處理方式:〔1〕進程退出〔exit〕——缺省動作;〔2〕進程忽略信號,就像沒有收到該信號一樣;〔3〕進程收到信號后執(zhí)行一個特殊的用戶函數(shù)。通過系統(tǒng)調(diào)用signal來定義進程的動作。oldfunction=signal(signum,function)signum——軟中斷信號號function——函數(shù)地址。function=0進程在核心態(tài)下退出〔exit〕function=1進程忽略以后出現(xiàn)的該信號oldfunction——最近一次為信號signum所定義的函數(shù)的值7.3進程組1、進程組標(biāo)識號用于標(biāo)識一組相關(guān)的進程,這組進程對于某些事件將收到共同的信號。2、系統(tǒng)調(diào)用setpgrp初始化一個進程的進程組號,將組號設(shè)置為與該進程的進程標(biāo)識號相同的值。grp=setpgrp()其中g(shù)rp為新的進程組號,在系統(tǒng)調(diào)用fork期間,子進程繼承其父進程的進程組號。7.4從進程發(fā)送軟中斷信號進程使用系統(tǒng)調(diào)用kill來發(fā)送軟中斷信號:kill(pid,signum)其中signum是要發(fā)送的軟中斷信號號,pid為軟中斷信號接收進程,pid的值與對應(yīng)進程的關(guān)系如下:1、pid為正值,信號發(fā)送給進程號為pid的進程;2、pie為0,信號發(fā)送給與發(fā)送者同組的所有進程;3、pid為-1,信號發(fā)送給真正用戶標(biāo)識號等于發(fā)送者的有效用戶標(biāo)識號的所有進程。4、pid為負(fù)數(shù)但非-1,信號發(fā)送給組號為pid絕對值所有進程。使用系統(tǒng)調(diào)用setpgrp的例子:#include<signal.h>main(){registerinti;setpgrp();for(i=0;i<10;i++){if(fork()==0){/*子進程*/if(i&1)setpgrp();printf(“pid=%dpgrp=%d\n”,getpid(),getpgrp());pause();/*掛起進程執(zhí)行的系統(tǒng)調(diào)用*/}}kill(0,SIGINT);}程序功能:向所有與父進程同組的進程發(fā)送軟中斷信號。其中共有5個子進程〔偶數(shù)〕與父進程同組,收到軟中斷信號后退出;另外5個子進程〔奇數(shù)〕因重新設(shè)置了組號而與父進程不同組,收不到軟中斷信號而繼續(xù)掛起。7.5進程的終止UNIX系統(tǒng)中的進程都是執(zhí)行系統(tǒng)調(diào)用exit來終止運行。進程進入僵死狀態(tài)后,釋放占用的資源,撤出進程的上下文,但保存進程的proc表項。exit(status)其中status是僵死進程發(fā)送給父進程的狀態(tài)值。進程可以顯式地調(diào)用exit,也可以在程序的結(jié)尾隱含地調(diào)用。算法exit輸入:給父進程的返回碼輸出:無{忽略所有軟中斷信號;if〔是與控制終端關(guān)聯(lián)的進程組組長〕{向該進程組中的所有組員發(fā)送掛起信號;將所有組員的進程組號設(shè)置為0;}關(guān)閉所有翻開的文件;釋放當(dāng)前工作目錄;釋放改變的根目錄〔如果設(shè)置有“當(dāng)前根”的話〕;釋放進程占用的內(nèi)存;寫記賬記錄;設(shè)進程狀態(tài)為僵死狀態(tài);將所有子進程的父進程設(shè)置為1號進程〔init〕;假設(shè)有任何本進程的子進程僵死,那么向init發(fā)送“子進程死”信號;向父進程發(fā)送“子進程死”信號;上下文切換;}不再接收任何中斷信號了告訴子進程準(zhǔn)備結(jié)束運行防止后續(xù)某新進程獲得本進程釋放的進程號,又成為新的進程組組長,從而與本進程組原來的組員混淆將本進程及所有子進程的運行時間、內(nèi)存、I/O累計到proc表項和全局記賬文件中使本進程從原進程樹中斷開,不再管理子進程了。main(){intchild;if((child=fork()==0){printf(“childPID%d\n”,getpid());pause();}printf(“childPID%d\n”,child);exit(child);}exit的例子:一個進程創(chuàng)立一個子進程。子進程打印自己的進程號后,執(zhí)行系統(tǒng)調(diào)用pause掛起自己,直到收到一個軟中斷信號。父進程打印子進程的進程號后退出,并返回子進程的PID作為狀態(tài)碼。對子進程而言,盡管父進程已死,子進程仍可繼續(xù)運行下去,直到收到軟中斷信號為止。7.6等待進程的終止
進程通過系統(tǒng)調(diào)用wait使自己的執(zhí)行與子進程的終止同步:pid=wait(stat_addr)其中pid是僵死子進程的進程號,stat_addr是一個整數(shù)在用戶空間的地址,它含有子進程的退出狀態(tài)碼,即exit的返回值。150stat_addr子進程exit的返回值算法wait輸入:存放退出進程的狀態(tài)的變量地址輸出:子進程標(biāo)識號,子進程退出碼{if〔本進程沒有子進程〕return〔錯誤〕;for〔;;〕{if〔本進程有僵死子進程〕{取任意一個僵死子進程;將子進程的CPU使用量累加到父進程;釋放子進程的進程表項proc;return〔子進程的進程標(biāo)識號,子進程的退出碼〕;}if〔本進程沒有子進程〕return〔錯誤〕;睡眠在可中斷的優(yōu)先級上;}}并且不忽略“子進程死”軟中斷信號并無特定的睡眠等待事件,而是被“子進程死”軟中斷信號喚醒等待并忽略子進程死軟中斷信號的例子#include<signal.h>main(intargc,*argv[]){inti,ret_val,ret_code;if(argc>1)signal(SIGCLD,SIG_IGN);/*忽略“子進程死”軟中斷信號/*for(i=0;i<15;i++)if(fork()==0){printf(“childproc%x\n”,getpid());exit(i);/*把當(dāng)前的i值〔子進程順序號〕返回給父進程*/}ret_val=wait(&ret_code);printf(“waitret_val%xret_code%x\n”,ret_val,ret_code);}本程序功能:
無參數(shù)運行時,等待任何一個子進程死;
有參數(shù)運行時,等待所有子進程死。7.7shell程序/*讀命令行直到文件尾EOF*/while(read(stdin,buffer,numcnars)){/*分析命令行*/if(命令行中含有&)amper=1;elseamper=0;/*對于非shell的內(nèi)部命令,即是操作系統(tǒng)的命令*/if(fork()==0)/*由子進程來執(zhí)行命令*/{/*是否為標(biāo)準(zhǔn)輸入輸出重定向?*/if(標(biāo)準(zhǔn)輸出重定向){fd=creat(newfile,fmask);close(stdout);dup(fd);close(fd);}if(建立管道){pipe(fildes);if(fork()==0){/*管道前面的命令,重定向標(biāo)準(zhǔn)輸出到管道去*/close(stdout);dup(fildes[1]);close(fildes[1]);close(fildes[0]);/*子進程執(zhí)行命令*/execlp(command1,command1,0);}/*管道后面的命令,重定向標(biāo)準(zhǔn)輸入從管道來*/
溫馨提示
- 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)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年禮品選購合同正式文本
- 跨媒體內(nèi)容分發(fā)-深度研究
- 界面科學(xué)與材料界面-深度研究
- 競爭對手市場份額分析-深度研究
- 虛擬人情感識別算法-深度研究
- 跨境考古與文化融合-深度研究
- 船舶維護成本控制-深度研究
- 海洋油氣勘探新方法-深度研究
- 生態(tài)旅游與遺產(chǎn)保護-深度研究
- 語義解析框架構(gòu)建-深度研究
- 老年病科重點專科建設(shè)
- 歌劇卡門課件教學(xué)課件
- 工程投標(biāo)文件范本完整版
- 小學(xué)二年級開學(xué)家長會課件2024-2025學(xué)年
- 光伏發(fā)電績效考核管理
- 低空經(jīng)濟無人機行業(yè)市場趨勢與競爭分析
- 信息論與編碼理論-全
- 正是橙黃橘綠時讀書分享好書推介感悟教學(xué)課件
- 舌尖上的美食中國美食文化北京小吃介紹
- 南方全站儀NTS-332R說明書
- 2024年航空職業(yè)技能鑒定考試-航空乘務(wù)員考試近5年真題附答案
評論
0/150
提交評論