進(jìn)程調(diào)度與系統(tǒng)調(diào)用.ppt_第1頁(yè)
進(jìn)程調(diào)度與系統(tǒng)調(diào)用.ppt_第2頁(yè)
進(jìn)程調(diào)度與系統(tǒng)調(diào)用.ppt_第3頁(yè)
進(jìn)程調(diào)度與系統(tǒng)調(diào)用.ppt_第4頁(yè)
進(jìn)程調(diào)度與系統(tǒng)調(diào)用.ppt_第5頁(yè)
已閱讀5頁(yè),還剩122頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、Linux操作系統(tǒng)內(nèi)核分析,湘潭大學(xué)信息工程學(xué)院,講課內(nèi)容,中斷管理 進(jìn)程管理 信號(hào)處理,中斷的概念,改變處理器正常執(zhí)行順序的事件 中斷來(lái)源: 硬件:時(shí)鐘、鍵盤、硬盤等,異步發(fā)生 異常:CPU檢測(cè)到的錯(cuò)誤 軟件 系統(tǒng)調(diào)用:進(jìn)程向OS發(fā)出的請(qǐng)求,中斷向量,保護(hù)模式支持256個(gè)中斷,每個(gè)中斷用一個(gè)0到255的整數(shù)來(lái)標(biāo)識(shí),把這個(gè)整數(shù)稱為中斷向量 0到31對(duì)應(yīng)異常(P76表5-2) 32到47對(duì)應(yīng)硬件中斷(P9圖2-5) 48到255預(yù)留,linux使用了0 x80作為系統(tǒng)調(diào)用,中斷,保護(hù)模式下中斷處理,idtr,0號(hào)中斷描述符,1號(hào)中斷描述符,2號(hào)中斷描述符,3號(hào)中斷描述符,中斷描述符表,中斷描述符

2、,段選擇子,段內(nèi)偏移(0-15),段內(nèi)偏移(16-31),2位,4位,Head中對(duì)中斷描述符表的處理,在程序232行(P58),定義了有256個(gè)中斷描述符的中斷描述符表,并在程序開始處把該描述符表的基地址輸出(可以被C程序使用) 在程序78行(P54),把這256個(gè)中斷描述符中的處理程序設(shè)置為ignore_int 在程序105行(P55)把中斷描述符表的基地址裝入到idtr寄存器中,gcc嵌入?yún)R編,_asm_ _volatile_( 匯編語(yǔ)句 : 輸出寄存器 : 輸入寄存器 : 會(huì)被修改的寄存器); 輸出寄存器:“=代表寄存器的字母” (變量名) 寄存器的值會(huì)被寫入變量中 輸入寄存器:“代表寄

3、存器的字母” (變量名) 用變量的值初始化寄存器,P81,常用寄存器加載代碼,P83表5-3,嵌入?yún)R編示例,#define _save_flags(x) _ asm_ _volatile_( “pushfl;” “popl %0” : “=a” (x) );,a代表寄存器eax。把eax和變量x綁定,往eax中寫入值等于給變量x賦值,數(shù)字代表寄存器的序號(hào)。把輸出寄存器和輸入寄存器按照順序進(jìn)行編號(hào),從0開始。%n代表第n個(gè)寄存器。,序號(hào)0,嵌入?yún)R編示例,#define get_seg_byte(seg,addr)( register char _res; _ _asm_ _(“ push %fs

4、; mov %ax, %fs; movb %fs:%2,%al; pop %fs” :“=a”(_res) :“0”(seg), “m”(*(addr); _res; ),序號(hào)0,序號(hào)1,序號(hào)2,宏的返回值,eax用seg的值進(jìn)行了初始化,_set_gate宏,_set_gate宏(定義在system.h,P390的22行),用來(lái)設(shè)置中斷描述符 gate_addr:描述符的地址 type:描述符的類型 dpl: 使用描述符的最低權(quán)限 addr:中斷處理函數(shù)的地址,_set_gate宏,#define _set_gate(gate_addr,type,dpl,addr) _asm_ (movw

5、%dx,%axnt movw %0,%dxnt movl %eax,%1nt movl %edx,%2 : : i (short) (0 x8000+(dpl13)+(type8), o (*(char *) (gate_addr), o (*(4+(char *) (gate_addr), d (char *) (addr),a (0 x00080000),0,1,2,3,4,_set_gate宏,0號(hào)立即數(shù),1號(hào)內(nèi)存地址指向描述符的基地址(前4個(gè)字節(jié)),2號(hào)內(nèi)存地址指向描述符的基地址+4(后4個(gè)字節(jié)),處理程序高16位,處理程序低16位,edx,0 x0008,0 x0000,eax,處理

6、程序低16位,0 x8000+(dpl13)+(type8),0 x8000+(dpl13)+(type8),段選擇子,段內(nèi)偏移(0-15),段內(nèi)偏移(16-31),Type,0,DPL,1,00000000,設(shè)置中斷描述符,#define set_trap_gate(n,addr) _set_gate( _ _asm_ _ volatile(“int $0 x80 : “=a”(_res) : “0”(_NR_#name); if(_res =0) return (type)_res; errno = - _res; return -1; ,系統(tǒng)調(diào)用的返回放在eax中,系統(tǒng)調(diào)用的功能號(hào)放在e

7、ax中(P381),使用系統(tǒng)調(diào)用,P63第23行 static inline _syscall0(int,fork) int fork(void) long _res; _ _asm_ _ volatile(“int $0 x80 : “=a”(_res) : “0”(_NR_fork); if(_res =0) return (type)_res; errno = - _res; return -1; ,使用系統(tǒng)調(diào)用,系統(tǒng)調(diào)用的輸入 把子功能號(hào)放入eax中 如果還有其它參數(shù)(最多3個(gè)),則第1、第2和第3個(gè)參數(shù)分別放入寄存器ebx,ecx和edx中 系統(tǒng)調(diào)用的返回值保存在eax中,數(shù)據(jù)結(jié)構(gòu)及

8、算法,函數(shù)指針數(shù)組 sys_call_talbe (P409) system_call(P86第80行)處理流程 保存現(xiàn)場(chǎng) 以子功能號(hào)作為索引查找sys_call_table,找到處理該功能的C語(yǔ)言函數(shù),然后調(diào)用該函數(shù)。 恢復(fù)現(xiàn)場(chǎng),系統(tǒng)調(diào)用的處理,cmpl $nr_system_calls-1,%eax ja bad_sys_call push %ds push %es push %fs pushl %edx pushl %ecx pushl %ebx movl %0 x10, %edx mov %dx,%ds mov %dx,%es movl %0 x17, %edx mov %dx,%fs

9、 call _sys_call_table(,%eax,4) pushl %eax,EFLAGS,EIP,用戶態(tài)ESP,用戶態(tài)SS,EDX,ECX,EBX,系統(tǒng)調(diào)用參數(shù),_sys_call_table+4*eax _sys_call_table在P409定義,EAX,保存系統(tǒng) 調(diào)用返回值,系統(tǒng)調(diào)用的處理,3:popl %eax popl %ebx popl %ecx popl %edx pop %fs pop %es pop %ds iret,EFLAGS,EIP,用戶態(tài)ESP,用戶態(tài)SS,EDX,ECX,EBX,EAX,講課內(nèi)容,中斷管理 進(jìn)程管理 信號(hào)處理,進(jìn)程的概念,進(jìn)程是程序的一次執(zhí)行

10、,是由代碼段、數(shù)據(jù)段和堆棧段組成動(dòng)態(tài)的實(shí)體,在Linux中,把進(jìn)程又稱為任務(wù)(task) 進(jìn)程是系統(tǒng)資源分配的基本單位,也是使用CPU運(yùn)行的基本調(diào)度單位,進(jìn)程描述符,為了管理進(jìn)程,操作系統(tǒng)需要清楚地知道每個(gè)進(jìn)程的屬性,Linux用一個(gè)稱為進(jìn)程描述符(task_struct)的數(shù)據(jù)結(jié)構(gòu)來(lái)描述 task_struct定義在sched.h中,參見P404第78行,進(jìn)程描述符狀態(tài),P12圖2-6,沒有實(shí)現(xiàn),進(jìn)程描述符線性地址分布,代碼,數(shù)據(jù),bss,用戶態(tài)堆棧,環(huán)境參數(shù),nr*64M,(nr+1)*64M,start_code,end_code,end_data,brk,start_stack,進(jìn)程描

11、述符任務(wù)狀態(tài)段,任務(wù)狀態(tài)段(TSS)是保存任務(wù)的所有信息的內(nèi)存段,共104B 寄存器保存區(qū)域 內(nèi)層堆棧指針區(qū)域 地址映射寄存器區(qū)域 其它字段 P116圖5-8,進(jìn)程描述符任務(wù)狀態(tài)段,在任務(wù)切換過(guò)程中 首先,CPU中各寄存器的當(dāng)前值被自動(dòng)保存到TR所指定的TSS中(當(dāng)前任務(wù)的TSS中) 然后,下一任務(wù)的TSS的選擇子被裝入TR 最后,從TR所指定的TSS中取出各寄存器的值送到處理器的各寄存器中 由此可見,通過(guò)在TSS中保存任務(wù)現(xiàn)場(chǎng)各寄存器狀態(tài)的完整映象,實(shí)現(xiàn)任務(wù)的切換,進(jìn)程描述符任務(wù)狀態(tài)段,TSS的段描述符在GDT中,當(dāng)前進(jìn)程的TSS的段選擇子被保存在TR寄存器中,TSS段描述符,GDT,TSS

12、段,當(dāng)前進(jìn)程的 TSS段選擇子,TR,TSS段描述符,TSS段,進(jìn)程描述符局部描述符表,局部描述符表(LDT)包含任務(wù)私有內(nèi)存段的描述符(也是一個(gè)內(nèi)存段) LDT的段描述符在GDT中,當(dāng)前進(jìn)程的LDT段選擇子在ldtr中,進(jìn)程描述符局部描述符表,Linux中LDT包含3個(gè)描述符,其中: 第0個(gè)沒用 第1個(gè)描述的是代碼段,該段的段選擇子是0 xf(1111) 第2個(gè)描述的是數(shù)據(jù)段,該段的段選擇子是0 x17(10111),進(jìn)程描述符局部描述符表,LDT段描述符,私有段段描述符,私有段段描述符,私有段段描述符,GDT,LDT,當(dāng)前進(jìn)程的 LDT段選擇子,ldtr,LDT段描述符,私有段段描述符,私

13、有段段描述符,私有段段描述符,TSS段描述符,TSS段描述符,進(jìn)程1,進(jìn)程2,Linux內(nèi)核堆棧,Intel平臺(tái)上進(jìn)程在不同的特權(quán)級(jí)別下使用不同的堆棧 在Linux中為進(jìn)程在內(nèi)核態(tài)建立的堆棧與進(jìn)程描述符公用一塊4K的內(nèi)存塊 參見shed.c(P95第53行),task_union,union task_union struct task_struct task; char stackPAGE_SIZE;/宏定義在mm.h(P401第4行) ;,內(nèi)核堆棧棧頂,任務(wù)描述符基地址,4K,任務(wù)數(shù)組,Linux把所有任務(wù)的進(jìn)程描述符的指針用一個(gè)指針數(shù)組管理起來(lái),定義在sched.c中(P95第65行)

14、struct task_struct *taskNR_TASKS; /NR_TASK=64,定義在sched.h中(P402第4行) FIRST_TASK LAST_TASK,taskn,task數(shù)組,tss,進(jìn)程數(shù)據(jù)段描述符,其它屬性,進(jìn)程描述符,沒用,內(nèi)核代碼段描述符,內(nèi)核數(shù)據(jù)段描述符,沒用,TSS0,LDT0,TSS1,LDT1,TSSn,LDTn,TSS(n+1),LDT(n+1),GDT,.,進(jìn)程代碼段描述符,沒用,進(jìn)程n,n*64,內(nèi)核態(tài)堆棧,求進(jìn)程n的TSS段的段選擇子,#define FIRST_TSS_ENTRY 4 #define _TSS(n) (unsigned lon

15、g) n)4)+(FIRST_TSS_ENTRY3) 定義在sched.h(P405第153和155行),4*8,16B,16B,GDT,Index,0,00,RPL,TI,(4+n*2)*8,進(jìn)程管理,進(jìn)程0的創(chuàng)建 創(chuàng)建子進(jìn)程 調(diào)度進(jìn)程 進(jìn)程睡眠 終止進(jìn)程,進(jìn)程0,進(jìn)程0是一個(gè)特殊的進(jìn)程 它是所有其他進(jìn)程的祖先進(jìn)程; 所有其他的進(jìn)程都是通過(guò)fork系統(tǒng)調(diào)用,復(fù)制進(jìn)程0或者其后代進(jìn)程產(chǎn)生的;只有進(jìn)程0是靜態(tài)產(chǎn)生的。,進(jìn)程0,創(chuàng)建進(jìn)程0的步驟 申請(qǐng)一個(gè)進(jìn)程描述符與進(jìn)程內(nèi)核堆棧的公用體 把進(jìn)程描述符的地址放在task數(shù)組的第0項(xiàng) 在GDT中設(shè)置進(jìn)程0的tss段描述符和ldt段描述符(sched_i

16、nit函數(shù), P102第392,393行) 把進(jìn)程0tss段描述符的選擇子和ldt段描述符的選擇子裝載到tr寄存器和ldtr寄存器(404,405行),申請(qǐng)進(jìn)程描述符與內(nèi)核堆棧的公用體,static union task_union init_task = INIT_TASK,; /定義在sched.c中(P95第58行) /INIT_TASK定義在sched.h中(P405第113行) /進(jìn)程0的代碼段和數(shù)據(jù)段與內(nèi)核代碼段和數(shù)據(jù)段重合 struct task_struct *taskNR_TASKS = /定義在sched.c中(P95第65行),task數(shù)組,tss,進(jìn)程數(shù)據(jù)段描述符,其它

17、屬性,進(jìn)程描述符,沒用,內(nèi)核代碼段描述符,內(nèi)核數(shù)據(jù)段描述符,沒用,TSS0,LDT0,GDT,進(jìn)程代碼段描述符,沒用,進(jìn)程0,64M,0M,esp0,內(nèi)核態(tài)堆棧,tr,ldt,1,2,2,3,4,加載進(jìn)程0的tss和ldt的段選擇子,ltr(0); lldt(0); #define ltr(n) _asm_(ltr %ax:a (_TSS(n) #define lldt(n) _asm_(lldt %ax:a (_LDT(n) /定義在sched.h中(P405第157行),把進(jìn)程0移到用戶態(tài),sched_init函數(shù)運(yùn)行完之后,進(jìn)程0還是運(yùn)行在內(nèi)核態(tài) 利用模擬中斷返回的方法把進(jìn)程0從內(nèi)核態(tài)切

18、換到用戶態(tài) move_to_user_mode定義在system.h中(P389第1行),Iret指令,EIP,CS,FLAG,SS,ESP,esp,內(nèi)核態(tài)堆棧,0 xf,0 x17,move_to_user_mode,#define move_to_user_mode() _asm_ ( “movl %esp,%eaxnt pushl $0 x17nt pushl %eaxnt pushflnt pushl $0 x0fnt pushl $1fnt iretn 1:tmovl $0 x17,%eaxnt movw %ax,%dsnt movw %ax,%esnt movw %ax,%fsnt

19、 movw %ax,%gs :ax),進(jìn)程0用戶態(tài)數(shù)據(jù)段選擇子(0 x17),進(jìn)程0用戶態(tài)堆棧指針( user_stack ),EFLAGS,進(jìn)程0代碼段段選擇子(0 x0f),EIP(iret返回后執(zhí)行的代碼),進(jìn)程管理,進(jìn)程0的創(chuàng)建 創(chuàng)建子進(jìn)程 調(diào)度進(jìn)程 進(jìn)程睡眠 終止進(jìn)程,fork系統(tǒng)調(diào)用,系統(tǒng)調(diào)用處理函數(shù)_sys_fork定義在system_call.s中(P89第208行),在task數(shù)組中 尋找一個(gè)空位,有空位,拷貝當(dāng)前進(jìn)程,有,無(wú),在task數(shù)組中尋找空位,int find_empty_process(void) 定義在fork.c(P115第135行) 作用:尋找task數(shù)組中

20、的空位 返回:如果找到則返回空位索引 否則返回錯(cuò)誤,find_empty_process,int i; repeat: if (+last_pid)pid = last_pid) goto repeat; for(i=1 ; iNR_TASKS ; i+) if (!taski) return i; return -EAGAIN;,last_pid記錄的是上一次創(chuàng)建進(jìn)程的進(jìn)程號(hào)。在Linux中,所有現(xiàn)存的進(jìn)程的進(jìn)程號(hào)不能相同。定義在fork.c中(P113第22行),拷貝當(dāng)前進(jìn)程,int copy_process(int nr, long ebp, long edi, long esi,lon

21、g gs, long none, long ebx, long ecx, long edx, long fs, long es, long ds, long eip, long cs, long eflags, long esp, long ss) 作用:拷貝當(dāng)前進(jìn)程的描述符到子進(jìn)程描述符中 返回:子進(jìn)程的進(jìn)程號(hào)(P114),調(diào)用copy_process的堆棧,CS,EFLAGS,EIP,用戶態(tài)ESP,用戶態(tài)SS,DS,ES,FS,EDX,ECX,EBX,call _sys_call_table的返回地址,GS,ESI,EDI,EBP,EAX,call _copy_process的返回地址,函

22、數(shù)的參數(shù),find_empty_process()的返回值,task數(shù)組空閑項(xiàng)的下標(biāo),系統(tǒng)調(diào)用的返回地址,Fork系統(tǒng)調(diào)用,int fork(void) long _res; _ _asm_ _ volatile(“int $0 x80 : “=a”(_res) : “0”(_NR_fork); if(_res =0) return (type)_res; errno = - _res; return -1; ,eip,copy_mem,int copy_mem(int nr,struct task_struct * p) 作用:修改子進(jìn)程的私有段的基地址, 并拷貝當(dāng)前進(jìn)程的頁(yè)目錄項(xiàng)和頁(yè)表 參

23、數(shù):nr子進(jìn)程在task數(shù)組中的索引 p 子進(jìn)程描述符的指針 返回:0表示無(wú)錯(cuò),小于0表示有錯(cuò),線性地址的分布,4G的線性地址給64個(gè)進(jìn)程使用,每個(gè)進(jìn)程占64M的線性地址 task數(shù)組中的第n個(gè)進(jìn)程占用的線性地址是n*64M(n+1)*64M task數(shù)組中的第n個(gè)進(jìn)程的所有段的基地址設(shè)為n*64M,taskn2,taskn1,task數(shù)組,進(jìn)程數(shù)據(jù)段,進(jìn)程代碼段,進(jìn)程數(shù)據(jù)段,進(jìn)程數(shù)據(jù)段,進(jìn)程代碼段,進(jìn)程數(shù)據(jù)段,n2*64M,(n2+1)*64M,n1*64M,(n1+1)*64M,線性地址,子進(jìn)程,父進(jìn)程,task 數(shù)組,線性地址,頁(yè)目錄,頁(yè)表,copy_process,申請(qǐng)4K頁(yè)面,設(shè)置t

24、ask數(shù)組,拷貝父進(jìn)程描述符,修改子進(jìn)程描述符,拷貝父進(jìn)程的 頁(yè)目錄和頁(yè)表,設(shè)置TSS和LDT,進(jìn)程管理,進(jìn)程0的創(chuàng)建 創(chuàng)建子進(jìn)程 調(diào)度進(jìn)程 進(jìn)程睡眠 終止進(jìn)程,任務(wù)切換的形式,ljmp TSS段選擇子:偏移 ljmp 8字節(jié)的內(nèi)存首地址 其中,頭4個(gè)字節(jié)對(duì)應(yīng)偏移(忽略),后4個(gè)字節(jié)的頭2個(gè)字節(jié)對(duì)應(yīng)TSS段選擇子,忽略,任務(wù)切換的步驟,從指令JMP的操作數(shù)中獲取新任務(wù)的TSS段選擇子 在當(dāng)前任務(wù)的TSS中保存當(dāng)前任務(wù)的狀態(tài) 為TR裝載新任務(wù)TSS的段選擇子,從新任務(wù)的TSS中裝載新任務(wù)的狀態(tài)到處理器中 開始執(zhí)行新任務(wù),schedule,void schedule() /定義在sched.c(P

25、96第104行) 作用:選擇一個(gè)任務(wù)并與當(dāng)前任務(wù)進(jìn)行切換,選擇task數(shù)組中第一個(gè) 所剩時(shí)間片最長(zhǎng)的且狀 態(tài)為可運(yùn)行的任務(wù),與當(dāng)前進(jìn)程進(jìn)行切換,所有的進(jìn)程 都已處理完,設(shè)置警告且警告超時(shí),給當(dāng)前進(jìn)程 設(shè)置alarm信號(hào),有信號(hào)并處于 可中斷睡眠狀態(tài),喚醒進(jìn)程,最長(zhǎng)時(shí)間片=0,重新給所有任務(wù)分配時(shí) 間片:counter/2+priority,是,否,是,否,是,否,否,是,switch_to宏,#define switch_to(n) struct long a,b; _tmp; _asm_(cmpl %ecx,currentnt je 1fnt movw %dx,%1nt xchgl %ecx

26、,currentnt ljmp *%0nt cmpl %ecx,last_task_used_mathnt jne 1fnt cltsn 1: :m (* ,dx中存放的是新進(jìn)程n的TSS段選擇子,1,0,2,3,從這里開始,老進(jìn)程退出CPU,新進(jìn)程開始運(yùn)行,除了剛用fork創(chuàng)建的進(jìn)程,其它進(jìn)程重新被運(yùn)行時(shí)都從這里開始,調(diào)用schedule,時(shí)鐘中斷發(fā)生時(shí) 發(fā)生中斷前,進(jìn)程處于用戶態(tài)且時(shí)間片=0,被動(dòng)放棄CPU(被搶奪),進(jìn)程的狀態(tài)仍然是可運(yùn)行狀態(tài) 系統(tǒng)調(diào)用返回時(shí) 發(fā)生中斷前,進(jìn)程處于用戶態(tài)且時(shí)間片=0,被動(dòng)放棄CPU(被搶奪),進(jìn)程的狀態(tài)仍然是可運(yùn)行狀態(tài) 睡眠函數(shù)內(nèi) 進(jìn)程在內(nèi)核態(tài)主動(dòng)放棄CP

27、U,進(jìn)程的狀態(tài)是不可運(yùn)行狀態(tài),時(shí)鐘中斷,Linux設(shè)置時(shí)鐘中斷頻率為10毫秒,每次中斷時(shí)調(diào)用timer_interrupt,定義在system_call.s(P88第176行),timer_interrupt: push %ds push %es push %fs pushl %edx pushl %ecx pushl %ebx pushl %eax movl $0 x10,%eax mov %ax,%ds mov %ax,%es movl $0 x17,%eax mov %ax,%fs incl jiffies movb $0 x20,%al outb %al,$0 x20 movl CS(

28、%esp),%eax andl $3,%eax pushl %eax call do_timer addl $4,%esp jmp ret_from_sys_call,EFLAGS,EIP,用戶態(tài)ESP,用戶態(tài)SS,EDX,ECX,EBX,EAX,fs指向進(jìn)程數(shù)據(jù)段,向8259A發(fā)送停止中斷信號(hào),取中斷發(fā)生時(shí)CS的CPL,CPL,do_timer,中斷時(shí)進(jìn)程 處于用戶態(tài),用戶態(tài)運(yùn)行時(shí)間+1,內(nèi)核態(tài)運(yùn)行時(shí)間+1,進(jìn)程的時(shí)間片-1,進(jìn)程時(shí)間片0,中斷時(shí)進(jìn)程 處于內(nèi)核態(tài),返回,schedule,是,是,否,是,否,否,P100第305行,系統(tǒng)調(diào)用返回時(shí),movl current,%eax cmpl

29、$0,state(%eax) jne reschedule cmpl $0,counter(%eax) je reschedule,P86第96行,進(jìn)程管理,進(jìn)程0的創(chuàng)建 創(chuàng)建子進(jìn)程 調(diào)度進(jìn)程 進(jìn)程睡眠 終止進(jìn)程,進(jìn)程睡眠,當(dāng)進(jìn)程請(qǐng)求的資源無(wú)效時(shí),進(jìn)程將會(huì)進(jìn)入睡眠狀態(tài),直到資源有效時(shí)。 每個(gè)資源上都會(huì)有一個(gè)等待隊(duì)列,在該隊(duì)列上排隊(duì)的就是為等待此資源而進(jìn)入睡眠狀態(tài)的進(jìn)程。,資源,進(jìn)程睡眠,進(jìn)程可以以兩種狀態(tài)進(jìn)入睡眠 不可中斷睡眠(sleep_on) 可中斷睡眠(interruptible_sleep_on),sleep_on,void sleep_on(struct task_struct *p

30、) /定義在sched.c(P97第151行) 作用:把任務(wù)設(shè)置為不可中斷睡眠,并把任 務(wù)掛在某個(gè)等待隊(duì)列上。 參數(shù):p等待隊(duì)列的頭指針,*p,p,進(jìn)程1 描述符,*p,p,進(jìn)程2 描述符,進(jìn)程1 描述符,*p,進(jìn)程4,tmp,進(jìn)程4 描述符,進(jìn)程3,tmp,進(jìn)程3 描述符,進(jìn)程2,tmp,進(jìn)程2 描述符,進(jìn)程1,tmp,進(jìn)程1 描述符,sleep_on,當(dāng)資源有效時(shí),在該資源等待隊(duì)列上的進(jìn)程全部都被喚醒。有可能還會(huì)發(fā)生資源沖突。 常見的使用的方法是 while(資源無(wú)效) sleep_on(資源等待隊(duì)列頭指針的指針);,interruptible_sleep_on,void interrup

31、tible_sleep_on( struct task_struct *p) /定義在sched.c(P97第167行) 作用:把任務(wù)設(shè)置為可中斷睡眠,并把任 務(wù)掛在某個(gè)等待隊(duì)列上。 參數(shù):p指向等待隊(duì)列的頭指針的指針,*p,進(jìn)程4,tmp,進(jìn)程4 描述符,進(jìn)程3,tmp,進(jìn)程3 描述符,進(jìn)程2,tmp,進(jìn)程2 描述符,進(jìn)程1,tmp,進(jìn)程1 描述符,*p,進(jìn)程4,tmp,進(jìn)程4 描述符,進(jìn)程3,tmp,進(jìn)程3 描述符,進(jìn)程2,tmp,進(jìn)程2 描述符,進(jìn)程1,tmp,進(jìn)程1 描述符,有信號(hào),interruptible_sleep_on,當(dāng)資源有效時(shí)或是任一進(jìn)程有信號(hào)時(shí),在該資源等待隊(duì)列上的進(jìn)程

32、全部都被喚醒。 資源沖突 沒有信號(hào)而被喚醒 常見的使用的方法是 while(資源無(wú)效,進(jìn)程管理,進(jìn)程0的創(chuàng)建 創(chuàng)建子進(jìn)程 調(diào)度進(jìn)程 進(jìn)程睡眠 終止進(jìn)程,進(jìn)程資源,進(jìn)程終止時(shí),要釋放它占用的所有資源,包括: 內(nèi)存 進(jìn)程描述符和內(nèi)核堆棧占用4K空間 頁(yè)表和頁(yè)目錄占用的物理頁(yè)面 代碼和數(shù)據(jù)占用的物理頁(yè)面 GDT中的LDT和TSS描述符 打開的文件,進(jìn)程,task 數(shù)組,線性地址,頁(yè)目錄,頁(yè)表,TSSn,LDTn,進(jìn)程終止的問題,通常父進(jìn)程在子進(jìn)程終止后,需要查詢子進(jìn)程的終止?fàn)顟B(tài),但是該狀態(tài)保存在子進(jìn)程的進(jìn)程描述符中。如果,子進(jìn)程終止時(shí)釋放了進(jìn)程描述符,則無(wú)法查詢終止?fàn)顟B(tài)。,通知,進(jìn)程終止的問題,由父

33、進(jìn)程負(fù)責(zé)回收子進(jìn)程的進(jìn)程描述符。但是,如果父進(jìn)程在子進(jìn)程之前終止,誰(shuí)來(lái)負(fù)責(zé)回收子進(jìn)程的進(jìn)程描述符? 進(jìn)程在終止時(shí),把所有未終止的子進(jìn)程過(guò)繼給進(jìn)程1。由進(jìn)程1負(fù)責(zé)接收這些子進(jìn)程終止信號(hào),并回收子進(jìn)程的進(jìn)程描述符。,sys_exit,int sys_exit(int error_code) /定義在exit.c(P111第137行) 作用:釋放進(jìn)程占用的物理內(nèi)存并關(guān)閉進(jìn)程打開的文件。 參數(shù):error_code 退出碼 返回:無(wú)意義,釋放代碼和數(shù)據(jù)占用 的物理內(nèi)存、頁(yè)表,把子進(jìn)程過(guò) 繼給進(jìn)程1,關(guān)閉打開的 文件和終端,修改狀態(tài)為僵死,schedule,發(fā)送信號(hào)給父進(jìn)程,sys_waitpid,in

34、t sys_waitpid(pid_t pid, unsigned long * stat_addr, int options) 作用:如果任意一個(gè)符合pid條件的子進(jìn)程僵死,則釋放子進(jìn)程占用的進(jìn)程描述符;如果所有符合pid條件的子進(jìn)程都不處于僵死狀態(tài),則按照option選項(xiàng)或者等待或立即返回。(P111第142行),sys_waitpid,參數(shù):pid pid 0等待進(jìn)程號(hào)為pid的子進(jìn)程 pid = 0等待進(jìn)程組號(hào)等于當(dāng)前進(jìn)程 組號(hào)的任何一個(gè)子進(jìn)程 pid = -1等待任何一個(gè)子進(jìn)程 pid -1等待進(jìn)程組號(hào)等于-pid的任 何一個(gè)子進(jìn)程,sys_waitpid,參數(shù): stat_addr

35、:存放子進(jìn)程的退出碼(P67) options: options中WNOHANG置位:表示如果沒有滿足pid標(biāo)識(shí)的子進(jìn)程是僵死狀態(tài),則當(dāng)前進(jìn)程馬上返回;否則當(dāng)前進(jìn)程掛起。 返回:正常返回子進(jìn)程的pid,出錯(cuò)返回負(fù)數(shù)。,所有進(jìn)程都搜索完畢,是符合pid條件的子進(jìn)程,子進(jìn)程的狀態(tài)是僵死,回收子進(jìn)程的 進(jìn)程描述符,有符合pid條件的子進(jìn)程,改狀態(tài)為可中斷睡眠 schedule,設(shè)置WNOHANG,收到SIGCHLD信號(hào),返回,是,否,是,否,否,是,是,否,是,否,是,否,講課內(nèi)容,中斷管理 進(jìn)程管理 信號(hào)處理,信號(hào),信號(hào)是一種進(jìn)程間通訊的方式,這種機(jī)制是異步的。 Linux支持32個(gè)信號(hào),每個(gè)信號(hào)

36、用一個(gè)整數(shù)值來(lái)標(biāo)識(shí)。參見書P107表5-5。,信號(hào)處理數(shù)據(jù)結(jié)構(gòu),參見task_struct,P404第83行 long signal; 對(duì)應(yīng)32個(gè)信號(hào),向進(jìn)程發(fā)送信號(hào)就是把singal中信號(hào)對(duì)應(yīng)的那一位置1。 signal |= 1(信號(hào)值-1) long blocked; 對(duì)應(yīng)32個(gè)信號(hào),如果某個(gè)信號(hào)對(duì)應(yīng)的那一位置1表示該信號(hào)被屏蔽。 signal /信號(hào)處理函數(shù)指針,可以是用戶自定義的函數(shù) sigset_t sa_mask; /在處理當(dāng)前信號(hào)時(shí)需要屏蔽的信號(hào),一般屏蔽本信號(hào) int sa_flags; /改變信號(hào)處理過(guò)程的標(biāo)志 void (*sa_restorer)(void); /恢復(fù)函

37、數(shù)入口地址,用于清除用戶堆棧這個(gè) /函數(shù)由libc提供,用戶無(wú)法自行設(shè)置 ;,P361第48行,信號(hào)處理數(shù)據(jù)結(jié)構(gòu),信號(hào)響應(yīng)函數(shù)是void(*)(int)類型的,內(nèi)核在signal.h第45行定義了兩個(gè)特殊的響應(yīng)函數(shù)。 #define SIG_DFL(void (*)(int)0) #define SIG_IGN(void (*)(int)1) 進(jìn)程對(duì)于SIG_DFL的處理一般是結(jié)束進(jìn)程,對(duì)于SIG_IGN一般是忽略,信號(hào)處理數(shù)據(jù)結(jié)構(gòu),在signal.h第37行由sa_flags標(biāo)志值的定義 #define SA_NOMASK0 x40000000 /在信號(hào)的處理后不保留信號(hào)屏蔽設(shè)置 #defi

38、ne SA_ONESHOT 0 x80000000 /信號(hào)處理函數(shù)一旦被調(diào)用過(guò),就恢復(fù)到SIG_DFL,使用信號(hào),其它模塊,信號(hào)管理,系統(tǒng)調(diào)用,sys_sigaction sys_signal sys_kill,send_sig,注冊(cè)信號(hào)處理函數(shù),這一步可以省略,在省略情況下信號(hào)的處理函數(shù)是SIG_DFL。參見進(jìn)程0的定義(P405第115行)。 進(jìn)程也可以注冊(cè)自己的信號(hào)處理函數(shù)。,注冊(cè)信號(hào)處理函數(shù),void sig_handler(int sig) printf(signal n); signal(SIGTERM,sig_handler); int main() signal(SIGTERM

39、,sig_handler); while(1); return 0; ,信號(hào)注冊(cè)系統(tǒng)調(diào)用,int sys_signal(int signum, long handler, long restorer) /P105第48行 作用:注冊(cè)一個(gè)自定義信號(hào)處理函數(shù) 參數(shù):signum信號(hào)值 handler信號(hào)處理函數(shù)指針 restorer恢復(fù)函數(shù) 返回:上一次注冊(cè)的處理函數(shù)指針,注冊(cè)信號(hào)處理函數(shù),voidmysignal(intsigno)/*mysignalhandler*/ int main(void)structsigactionact,old; act.sa_handler=mysignal;act.sa_flags=0;sigaction(SIGHUP, ,信號(hào)注冊(cè)系統(tǒng)調(diào)用,int sys_sigaction(int signum,

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(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)論