操作系統(tǒng)進(jìn)程管理課程設(shè)計(jì)報(bào)告_第1頁(yè)
操作系統(tǒng)進(jìn)程管理課程設(shè)計(jì)報(bào)告_第2頁(yè)
操作系統(tǒng)進(jìn)程管理課程設(shè)計(jì)報(bào)告_第3頁(yè)
操作系統(tǒng)進(jìn)程管理課程設(shè)計(jì)報(bào)告_第4頁(yè)
操作系統(tǒng)進(jìn)程管理課程設(shè)計(jì)報(bào)告_第5頁(yè)
已閱讀5頁(yè),還剩11頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、 分析Linux操作系統(tǒng)代碼 要求:1、給c語言源程序加上注釋, 2、劃分程序的模塊結(jié)構(gòu),并畫出主要模塊的流程圖3、用另外一種程序設(shè)計(jì)語言java,vb,或c#實(shí)現(xiàn)主要模塊的主要功能 南華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院課程設(shè)計(jì)報(bào)告 20 10 20 11 學(xué)年度 第 2 學(xué)期 課程名稱操作系統(tǒng)設(shè)計(jì)題目進(jìn)程管理專業(yè)船本09計(jì)算機(jī)班級(jí)01班分組成員負(fù)責(zé)任務(wù)駱兵 王榮 歐亞琪代碼收集和注釋劉利霞 肖明星流程圖設(shè)計(jì)總結(jié)1.題目要求描述在計(jì)算機(jī)中要執(zhí)行一個(gè)程序,首先將程序的代碼從硬盤讀入到內(nèi)存,然后CPU根據(jù)程序代碼指令一條一條的執(zhí)行,而這時(shí)候的程序就叫進(jìn)程,計(jì)算機(jī)中同時(shí)存在多個(gè)進(jìn)程在等待被執(zhí)行,比方你在用w

2、indow/Linux上網(wǎng)的時(shí)候,你一邊用QQ和朋友聊天,一邊在用MP3播放器聽音樂,一邊在瀏覽網(wǎng)頁(yè).那么這時(shí)候在計(jì)算機(jī)中就有三個(gè)進(jìn)程在同時(shí)運(yùn)行,一是QQ進(jìn)程,二是MP3播放器進(jìn)程,三是瀏覽器進(jìn)程.但是計(jì)算機(jī)中只有一個(gè)CPU,在一個(gè)時(shí)間點(diǎn)上,它只能運(yùn)行一個(gè)進(jìn)程的指令,比方在2005/11/29/日 08/23/42/秒時(shí)計(jì)算機(jī)的CPU執(zhí)行的是QQ進(jìn)程的一條加法(mov)指令.那么計(jì)算機(jī)是怎樣讓三個(gè)進(jìn)程同時(shí)運(yùn)行起來的呢(至少我們看來是這樣).在計(jì)算機(jī)內(nèi)部所有的正在運(yùn)行的進(jìn)程都在等待被CPU執(zhí)行,操作系統(tǒng)按一定的規(guī)律讓所有的進(jìn)程都得到CPU的執(zhí)行.方法是一會(huì)兒讓QQ進(jìn)程執(zhí)行,過了一定時(shí)間后又讓MP

3、3播放器進(jìn)程得到CPU的執(zhí)行,再過一定時(shí)間后讓瀏覽器進(jìn)程得到CPU的執(zhí)行.相對(duì)于人的反響,CPU的執(zhí)行速度太快,所以人根本感覺不到這些進(jìn)程的切換過程,也不會(huì)對(duì)人的操作產(chǎn)生影響現(xiàn)在的問題是操作系統(tǒng)是按照什么樣的規(guī)律給個(gè)各進(jìn)程分配CPU資源的.操作系統(tǒng)是按照個(gè)各進(jìn)程的屬性來分配CPU資源的.那進(jìn)程的屬性在什么呢?當(dāng)操作系統(tǒng)創(chuàng)立一個(gè)進(jìn)程時(shí)都就為這個(gè)進(jìn)程分配了一定的內(nèi)存空間來存放它的屬性.在Linux操作系統(tǒng)中,操作系統(tǒng)定義了一個(gè)數(shù)據(jù)結(jié)構(gòu)task_struct來描述各個(gè)進(jìn)程的進(jìn)程屬性,task_struct結(jié)構(gòu)叫進(jìn)程控制塊(PCB), 它是操作系統(tǒng)中重要的數(shù)據(jù)結(jié)構(gòu)之一.具體定義在中,注意在Linux操

4、作系統(tǒng)中所有的操作系統(tǒng)源代碼都在/usr/src目錄下.2.程序流程圖和源程序源碼分析 Linux進(jìn)程調(diào)度,系統(tǒng)管理 繼續(xù)監(jiān)聽 Linux進(jìn)程管理命令 Linux進(jìn)程管理以及文本編輯3.程序設(shè)計(jì)task_struct結(jié)構(gòu)的代碼如下所示:/include/linux/sched.h struct task_struct volatile long state; /* 進(jìn)程的狀態(tài),在代碼后面有說明*/unsigned long flags; /* 進(jìn)程標(biāo)志 */int sigpending; mm_segment_t addr_limit; /* 線性地址空間: 0-0 xBFFFFFFF 為用戶

5、線性空間地址; 0-0 xFFFFFFFF 為內(nèi)核線性空間地址 */struct exec_domain *exec_domain; volatile long need_resched; unsigned long ptrace; int lock_depth; long counter; /* 進(jìn)程的動(dòng)態(tài)優(yōu)先級(jí),在代碼后面有說明 */long nice; /* 進(jìn)程的靜態(tài)優(yōu)先級(jí),在代碼后面有說明 */unsigned long policy; /* 進(jìn)程采用的調(diào)度策略,在代碼后面有說明 */struct mm_struct *mm; /* 進(jìn)程屬性中指向內(nèi)存管理的數(shù)據(jù)結(jié)構(gòu)mm_struct

6、d的指針,在代碼后面有說明 */int has_cpu, processor; unsigned long cpus_allowed; struct list_head run_list; unsigned long sleep_time; struct task_struct *next_task , *prev_task; /* 所以進(jìn)程通過這兩個(gè)指針組成一個(gè)雙向鏈表*/struct mm_struct *active_mm; /* 指向活動(dòng)地址空間,在后面的代碼有說明 */ /* task state */struct linux_binfmt *binfmt; int exit_cod

7、e, exit_signal;int pdeath_signal; unsigned long personality; int did_exec:1; int dumpable:1; pid_t pid; /* 進(jìn)程標(biāo)志符,在代碼后面有說明 */pid_t pgrp; /* 進(jìn)程組標(biāo)號(hào),在代碼后面有說明 */pid_t tty_old_pgrp; pid_t session; pid_t tgid; int leader; struct task_struct *p_opptr, *p_pptr, *p_cptr, *p_ysptr, *p_osptr; /* 這五個(gè)標(biāo)志表示一個(gè)進(jìn)程的在計(jì)算

8、機(jī)中的親屬關(guān)系,分別標(biāo)志祖先進(jìn)程,父進(jìn)程,子進(jìn)程,弟進(jìn)程和兄進(jìn)程,為了在兩個(gè)進(jìn)程之間共享方便而設(shè)立 */struct list_head thread_group; struct task_struct *pidhist_next; struct task_struct *pidhist_pprev; /* 上面兩個(gè)指針是為了在計(jì)算機(jī)中快速查一個(gè)進(jìn)程而設(shè)立,具體方式以后講*/wait_queue_head_t wait_chldexit; struct completion *vfork_sem; unsigned long rt_priority; /* 實(shí)時(shí)進(jìn)程的優(yōu)先級(jí)標(biāo)志*/ unsig

9、ned long it_real_value, it_prof_value, it_virt_value; unsigned long it_real_incr, it_prof_incr, it_virt_incr; struct timer_list real_timer; struct tms times; struct tms group_times;unsigned long start_time; long per_cpu_utimeNR_CPUS, per_cpu_stimeNR_CPUS; unsigned long min_flt, maj_flt, nswap, cmin_

10、flt, cmaj_flt, cnswap; int swappable:1; uid_t uid,euid,suid,fsuid; gid_t gid,egid,sgid,fsgid; int ngroups; gid_t groupsNGROUPS; kernel_cap_t cap_effective, cap_inheritable, cap_permitted; int keep_capabilities:1; struct user_struct *user; struct rlimit rlimRLIM_NLIMITS; unsigned short used_math; cha

11、r comm16; int link_count; struct tty_struct *tty; /* NULL if no tty */unsigned int locks; /* How many file locks are being held */struct sem_undo *semundo; struct sem_queue *semsleeping; struct thread_struct thread; struct fs_struct *fs; /* 進(jìn)程屬性中指向和文件管理有關(guān)的數(shù)據(jù)結(jié)構(gòu)*/ struct files_struct *files; spinlock_

12、t sigmask_lock; struct signal_struct *sig; sigset_t blocked; struct sigpending pending; unsigned long sas_ss_sp; size_t sas_ss_size; int (*notifier)(void *priv); void *notifier_data; sigset_t *notifier_mask; u32 parent_exec_id; u32 self_exec_id; spinlock_t alloc_lock; spinlock_t switch_lock;程序說明如下:

13、volatile long state 定義了進(jìn)程的狀態(tài),進(jìn)程總共有6種狀態(tài)標(biāo)志,分別是:一. TASK_RUNING. (正在運(yùn)行狀態(tài)或者是可運(yùn)行狀態(tài))二. TASK_INTERRUPTIBLE,(可打斷睡眠狀態(tài))三. TASK_UNINTERRUPTIBLE,(不可打斷睡眠狀態(tài))四. TASK_ZOMBLE. (僵死狀態(tài))五. TAKS_STOPPED.(暫停狀態(tài))六. 交換狀態(tài).這六種屬性標(biāo)志了此進(jìn)程現(xiàn)在的狀態(tài),各種不同的狀態(tài)決定了進(jìn)程什么時(shí)候獲得CPU而被執(zhí)行.正在運(yùn)行狀態(tài)是當(dāng)前正在運(yùn)行進(jìn)程的狀態(tài).也就是說他的volatile long state被標(biāo)志成TASK_RUANING.可運(yùn)

14、行狀態(tài)是那些正在等待CPU資源的進(jìn)程的狀態(tài),這些進(jìn)程在就緒隊(duì)列run-queqe中.這些進(jìn)程只要得到CPU在個(gè)資源就馬上可以被運(yùn)行.其也標(biāo)志也為TASK_RUANING.可打斷睡眠狀態(tài)是哪些在等待隊(duì)列中等待除CPU之外的其它資源的進(jìn)程,只要它們所等待的資源到達(dá)就馬上可以從等待隊(duì)列進(jìn)入就緒隊(duì)列,狀態(tài)標(biāo)志也從TASK_INTERRUPTIBLE狀態(tài)變成TASK_RUANING可運(yùn)行狀態(tài).不可打斷睡眠狀態(tài)和可睡眠狀態(tài)類似,區(qū)別在于前者可以用信號(hào)喚醒,而后者不可以.僵死狀態(tài)是標(biāo)志那些已經(jīng)運(yùn)行完畢釋放了大局部資源并退出但還沒有釋放進(jìn)程控制快task_struct的進(jìn)程.暫停狀態(tài)是那些遇到突發(fā)情況或者收到

15、暫停信號(hào)而暫時(shí)停止運(yùn)行的進(jìn)程的狀態(tài). counter是進(jìn)程的動(dòng)態(tài)優(yōu)先級(jí),它定義了一個(gè)在就緒隊(duì)列的進(jìn)程當(dāng)它得到CPU后可運(yùn)行的時(shí)間,用靜態(tài)優(yōu)先級(jí)初始化,當(dāng)然計(jì)算機(jī)是以時(shí)鐘中斷做為時(shí)間的計(jì)數(shù)器,每發(fā)送一個(gè)時(shí)鐘中斷,動(dòng)態(tài)優(yōu)先級(jí)上的時(shí)間片就減少一個(gè)時(shí)鐘中斷的時(shí)間,時(shí)間片減到0的時(shí)候就退出該進(jìn)程而調(diào)度另一個(gè)進(jìn)程獲得CPU. nice是進(jìn)程的靜態(tài)優(yōu)先級(jí),當(dāng)一個(gè)在就緒隊(duì)列中的進(jìn)程獲得CPU之后,它被賦予此進(jìn)程可占有CPU的時(shí)間.這個(gè)時(shí)間被稱為時(shí)間片. policy是進(jìn)程的調(diào)度策略標(biāo)志.有三種調(diào)度標(biāo)志: SCHED_OTHER 普通進(jìn)程的調(diào)度策略,基于優(yōu)先權(quán)的輪轉(zhuǎn)法. SCHED_FIFO 實(shí)時(shí)進(jìn)程的調(diào)度策略

16、,基于先進(jìn)先出的算法. SCHED_RR 實(shí)時(shí)進(jìn)程的調(diào)度策略,基于優(yōu)先權(quán)的輪轉(zhuǎn)法.在linux中有兩種進(jìn)程,一種是普通進(jìn)程,一種的實(shí)時(shí)進(jìn)程,實(shí)時(shí)進(jìn)程的優(yōu)先級(jí)總是高于普通進(jìn)程,也就是說當(dāng)就緒隊(duì)列中即有實(shí)時(shí)進(jìn)程也有普通進(jìn)程時(shí),總是先運(yùn)行實(shí)時(shí)進(jìn)程.不同的進(jìn)程采用不同的調(diào)度策略. rt_priority 實(shí)時(shí)進(jìn)程的優(yōu)先級(jí). need_resched 標(biāo)志下一次有調(diào)度時(shí)機(jī)的時(shí)候是否調(diào)用此進(jìn)程.如果此進(jìn)程沒有沒有被用戶關(guān)閉或者其代碼全被執(zhí)行完了,在下一次調(diào)度時(shí)機(jī)應(yīng)該還被調(diào)用.如果被用戶關(guān)閉那么直接退出該進(jìn)程. mm_struct *mm mm_struct數(shù)據(jù)結(jié)構(gòu)是描述內(nèi)存存儲(chǔ)信息的數(shù)據(jù)結(jié)構(gòu),進(jìn)程控制塊t

17、ask_struct中用mm指針指想mm_struct數(shù)據(jù)結(jié)構(gòu).也就是在進(jìn)程的屬性中通過mm指針來管理起對(duì)應(yīng)的內(nèi)存區(qū).mm_struct *active_active 內(nèi)核線程用來指向調(diào)用它的普通進(jìn)程的內(nèi)存地址空間.當(dāng)普通進(jìn)程在運(yùn)行時(shí)如果發(fā)生系統(tǒng)調(diào)用,程序就會(huì)從用戶態(tài)轉(zhuǎn)為內(nèi)核態(tài),內(nèi)核態(tài)中執(zhí)行的是內(nèi)核線程,內(nèi)核線程沒有內(nèi)存空間地址結(jié)構(gòu)mm_struct,當(dāng)他需要內(nèi)存空間地址的時(shí)候就會(huì)調(diào)用用戶態(tài)對(duì)應(yīng)進(jìn)程的用以空間地址結(jié)構(gòu)mm_struct.內(nèi)核線程就是就是通過active_mm指針來指向用戶態(tài)進(jìn)程的mm_struct結(jié)構(gòu). pid_t pid pid是進(jìn)程標(biāo)志符,操作系統(tǒng)每創(chuàng)立一個(gè)新的進(jìn)程就要為這

18、個(gè)新進(jìn)程分配一個(gè)進(jìn)程控制快(PCB),那么系統(tǒng)內(nèi)核是怎樣區(qū)分這些進(jìn)程的呢?就是通過進(jìn)程標(biāo)志符pid,系統(tǒng)在為新的進(jìn)程分配進(jìn)程控制塊的候,它不是自己去創(chuàng)立,而是直接從上一個(gè)進(jìn)程中復(fù)制它的進(jìn)程控制塊,其中里面的大局部東西保存下來,只做少量的改動(dòng),然后它的進(jìn)程標(biāo)志符加1賦值給新的進(jìn)程控制塊. 進(jìn)程控制塊的總共有80多項(xiàng),在這里就不一一介紹了,以后我們?cè)趯W(xué)習(xí)過程用到什么屬性就介紹什么屬性,這樣在宏觀上把握,不至于被一個(gè)小小的進(jìn)程控制塊給擋住了. 接著上面的進(jìn)程說明,前面我們說了一下進(jìn)程的根本概念和它的屬性,接下來我們介紹一下在操作系統(tǒng)內(nèi)部是怎樣通過調(diào)度函數(shù)調(diào)度進(jìn)程的.我們?cè)谑褂糜?jì)算機(jī)的時(shí)候,可能同時(shí)翻

19、開了很多程序,比方同時(shí)翻開IE瀏覽器,QQ,word文檔等,那么這就意味著內(nèi)核要同時(shí)管理多個(gè)用戶進(jìn)程.這些進(jìn)程中每個(gè)進(jìn)程每隔一段時(shí)間就要被CPU執(zhí)行一次,所有的進(jìn)程都是這樣輪流執(zhí)行,在Linux操作系統(tǒng)中一個(gè)進(jìn)程占有CPU的時(shí)間為50ms(也就是5個(gè)時(shí)間滴答,關(guān)于時(shí)間滴答的概念后面介紹),這個(gè)時(shí)間對(duì)于人的反響來講是相當(dāng)快的,所以人更不感覺不到進(jìn)程的調(diào)度和切換,各個(gè)進(jìn)程也有輕重緩急之分,后面還會(huì)說一個(gè)goodness函數(shù),這個(gè)函數(shù)比擬簡(jiǎn)單,主要作用是綜合進(jìn)程屬性(進(jìn)程控制快)中的各種因素和數(shù)據(jù)算出每個(gè)進(jìn)程的權(quán)值,權(quán)值最大的進(jìn)程就是調(diào)度程序(schedule()最應(yīng)該調(diào)用的進(jìn)程.在計(jì)算機(jī)中進(jìn)程以六

20、種狀態(tài)存在,這在進(jìn)程的屬性里已經(jīng)有了介紹,其中存在于就緒隊(duì)列TASK_RUNNING中處于運(yùn)行狀態(tài)的進(jìn)程是等待計(jì)算機(jī)中唯一的資源CPU的進(jìn)程,它們只要一得到CPU就馬上可以被執(zhí)行,那么操作系統(tǒng)是安什么樣的規(guī)那么來讓這些進(jìn)程合理和公平的得到CPU的呢,這就要用到計(jì)算機(jī)的調(diào)度函數(shù)schedule(),_/kernel/sched。casmlinkage void schedule(void) struct schedule_data *sched_data; struct task_struct *prev, *next, *p; struct list_struct *tmp; int this

21、_cpu,c;if(!current-active_mm) BUG(); /* current指當(dāng)前進(jìn)程,當(dāng)前進(jìn)程所指的內(nèi)存空間如果為空,那么進(jìn)程必定有問題,出錯(cuò)返回 */need_resched_back: prev=current; this_cpu=prev-processor; if(in_interrupt() goto scheduling_in_interrupt; /*上面代碼的意思是: 將局部變量prev和this_cpu初始化為當(dāng)前進(jìn)程和當(dāng)前CPU.然后檢查schedule()是否中斷調(diào)用,假設(shè)是那么直接返回,其中g(shù)oto后面的轉(zhuǎn)到的地方在本程序中有定義,比方本進(jìn)程后面的s

22、cheduling_in_interrupt在本程序的最后有定義,意思是: 打印出Scheduling in interrupt字符后退出 */release_kernel_lock(prev,this_cpu); if(softirq_active(this_cpu) & softirq_mask(this_cpu) goto handle_softirq; /* 檢查是否有軟中斷請(qǐng)求,軟中斷softirq將在后面講解 */hand_softirp_back: sched_data= & aligned_datathis_cpu.schedule_data; spin_lock_irp(&r

23、unqueue_lock);/* 局部變量sched_data中保存當(dāng)前進(jìn)程的數(shù)據(jù)區(qū),*/ if(prev-policy = SCHED_RR) goto move_rr_last;* 當(dāng)前基于優(yōu)先權(quán)輪轉(zhuǎn)法的調(diào)度策略實(shí)時(shí)進(jìn)程,如果要調(diào)用它,先檢查其count是否0假設(shè)是,那么將其掛到運(yùn)行隊(duì)列的最后面.具體做法在后面的 move_rr_last中有定義 */move_rr_back: switch(prev-state) case TESK_INTERRUPTIBLE: if(sign_pending(prev) prev-state = TASK_RUNNING; break; default

24、: del_form_runqueue(prev); case TASK_RUNNING; prev-need_resched=0; /* 上面這段代碼意思是: 如果進(jìn)程的狀態(tài)為可中斷睡眠狀態(tài)且喚醒它的信號(hào)正在迫近,那么將其置為可運(yùn)行狀態(tài),如果狀態(tài)為運(yùn)行狀態(tài)那么忽略,如果狀態(tài)除上述兩種之外的其它狀態(tài)那么直接刪除.最后將neet_resched置為0,neet_resched置0意味著本能啟動(dòng)調(diào)度函數(shù)shchedule(); */repeat_schedule: next = idlt_task(this_cpu); c = -1000; if(prev-state = TASK_RUNNING

25、) goto still_running; /* 上面的代碼中的c是優(yōu)先級(jí)運(yùn)算函數(shù)goodness的一個(gè)變量,優(yōu)先級(jí)運(yùn)算函數(shù) goodness將是我們介紹的下一個(gè)函數(shù),它的返回值是進(jìn)程的權(quán)值,調(diào)度函數(shù)判斷緒隊(duì)列中權(quán)值最大的進(jìn)程就是最優(yōu)先要被調(diào)用的進(jìn)程.goodness的具體算法看下一個(gè)函數(shù).上面代碼的意思是: 將next設(shè)置為當(dāng)前cpu的idlt_task.將當(dāng)前優(yōu)先級(jí)的變量c賦值為-1000,其中-1000是goodness中最小的權(quán)值.然后判斷當(dāng)前進(jìn)程是否是可運(yùn)行進(jìn)程,假設(shè)是那么轉(zhuǎn)到still_running處執(zhí)行,still_running在本函數(shù)的后面有解釋.意思是: 將當(dāng)前進(jìn)程的go

26、odness值賦予goodness優(yōu)先級(jí)變量c并返回still_running_back: list_for_each(tmp,&runqueue_head) p = list_entry(tmp, struct task_struct, run_list); if(can_schedule(p,this_cpu) int weight = goodness(p,this_cpu,prev-active_mm); if(weightc) c=weight,next=p; /* 上面代碼的意思是: 遍歷整個(gè)就緒隊(duì)列,計(jì)算出每一個(gè)進(jìn)程的goodness權(quán)值并且與當(dāng)前進(jìn)程做比擬,選擇goodness

27、權(quán)值最大的那個(gè)進(jìn)程獲得cpu資源. */if(! c) goto recalculate; /* 上面代碼的意思是: 如果當(dāng)前goodness權(quán)值為0,那么運(yùn)行recalculate:,起代碼在后面有說明,意思是:重新計(jì)算每一進(jìn)程的優(yōu)先權(quán),最后轉(zhuǎn)到repeat_schedule:處執(zhí)行,repeat_schedule:局部在前面已經(jīng)有講過,自己看有會(huì)過頭去看一下吧 */sched_data-curr = next; /* 將當(dāng)前進(jìn)程信息保存到局部變量sched_data中*/#ifdef CONFIG_SMPnext-has_cpu = 1; next-processor = this_cpu

28、; /* 意思為: 將調(diào)度數(shù)據(jù)區(qū)指針指向下一個(gè)要調(diào)度的進(jìn)程并將當(dāng)前進(jìn)程的cpu設(shè)置為下一個(gè)進(jìn)程的當(dāng)前cpu. */#endifspin_unlock_irq(&runqueue_lock);if(prev = next) goto same_processor; /* 意思為: 如果當(dāng)前運(yùn)行的進(jìn)程的goodness還是隊(duì)列中所以進(jìn)程中最高的,也就是說下一個(gè)要調(diào)度的進(jìn)程還是當(dāng)前進(jìn)程.那么只要重新得到cpu控制權(quán)返回need_resched_back:處執(zhí)行. */ #ifdef CONFIG_SMPsched_data-last_schedule = get_cycles();#endifkst

29、at.context_swtch +;prepare_to_switch()struct mm_struct *mm = next-mm; struct mm_struct *oldmm = prev-active_mm; if(! mm) if(next-active_mm) BUG();next-active = oldmm; atomic_inc(&old_mm-mm_count); enter_lazy_tlb(oldmm,next,this_cpu); elseif(next-active_mm != mm) BUG();switch_mm(oldmm, mm, next, this

30、_cpu); if(! prev-mm)prev-active_mm = NULL; mmdrop(oldmm); switch_to(prev,next,prev); _scheduel_tail(prev); /* 上面的代碼是進(jìn)行進(jìn)程切換 */* 下面的代碼是前面代碼中g(shù)oto要轉(zhuǎn)到的地方 */same_processor: reacquire_kernel_lock(current); if(current - need_resched) goto need_resched_back; return; recalculate: struct task_struct *p; spin_u

31、nlock_irq(&runqueue_lock); read_lock(&tasklist_lock); fot_each_task(p) p-counter = (p-counter 1) + NICE_TO_TICKS(p_nice); read_unlock(&tasklist_lock); spin_lock_irq(&runqueue_lock); goto repeat_schedule; still_running: c = goodness(prev, this_cpu, precv-active_mm); next=prev; goto still_running_back

32、;handle_softirq: do_softirq();goto handle_softirq_back;move_rr_last: if(! prev-counter) prev-counter = NICE_TO_TICKS(prev_nice); move_last_runqueue(prev); goto move_rr_back; scheduling_in_interrupt: printf(“Scheduling in interrupt n); BUG();return();在上面的我們說了進(jìn)程調(diào)度程序schedule(),接著說一下上面的函數(shù)中用到的進(jìn)程優(yōu)先級(jí)的權(quán)值的運(yùn)行

33、函數(shù)googness();這個(gè)函數(shù)的作用很簡(jiǎn)單,就是算出就緒隊(duì)列中的進(jìn)程的優(yōu)先級(jí),然后調(diào)度程序調(diào)度優(yōu)先級(jí)最高的進(jìn)程獲得當(dāng)前CPU,計(jì)算機(jī)中進(jìn)程分為兩種,一為普通進(jìn)程,它的優(yōu)先級(jí)用進(jìn)程控制塊中的counter表示,二為實(shí)時(shí)進(jìn)程,實(shí)時(shí)進(jìn)程的優(yōu)先級(jí)用rt_priority表示,它在進(jìn)程控制塊中有定義,當(dāng)就緒隊(duì)列中同時(shí)存在兩種進(jìn)程的時(shí)候,實(shí)時(shí)進(jìn)程總是先于普通進(jìn)程運(yùn)行,它的實(shí)現(xiàn)機(jī)制是實(shí)時(shí)進(jìn)程的權(quán)值以1000做為根底值,也就是說實(shí)時(shí)進(jìn)程的權(quán)值是1000加上它的進(jìn)程優(yōu)先級(jí),而普通進(jìn)程的優(yōu)先級(jí)就是它的進(jìn)程優(yōu)先級(jí).整個(gè)函數(shù)比擬簡(jiǎn)單,但卻是操作系統(tǒng)內(nèi)核最為頻繁調(diào)用的函數(shù)之一,也直接關(guān)系到操作系統(tǒng)的性能.此函數(shù)如下

34、: _static inline int goodness(struct task_struct * p, int this_cpu, struct mm_struct this_mm) int weigth; weight=-1; / * 定義函數(shù)返回的權(quán)值weight并進(jìn)行初始化 */* 下面是普通進(jìn)程的處理情況 */ if(p-* & SCHED_YIELD) goto out; / * 如果要放棄本次調(diào)度,那么直接返回, 轉(zhuǎn)到的out處在后面有定義 */ if(p-policy = SCHED_OTHER) weight = p- counter;if(!weight) goto ou

35、t; /* 函數(shù)是普通進(jìn)程的情況,在這種情況下,進(jìn)程的權(quán)值直接為本進(jìn)程的剩余時(shí)間,如果剩余時(shí)間不存在或?yàn)?,那么直接返回 */#ifdef CONFIG_SMPif(p-processor = this_cpu) weight += PROC_CHANGE_PENALTY; #endifif(p-mm = this_mm | !p-mm) weight +=1; weight +=20-p-nice; goto out; /* 下面是實(shí)時(shí)進(jìn)程的處理情況 */ weight = 1000 + p-re_priority;/* 實(shí)時(shí)進(jìn)程的權(quán)值至少為1000,也就說它的權(quán)值是它是基數(shù)1000加上實(shí)時(shí)

36、進(jìn)程的優(yōu)先級(jí),其中實(shí)時(shí)進(jìn)程的優(yōu)先級(jí)用re_priority表示,re_priority在進(jìn)程的屬性中有定義, out: return weight; /* 前面的代碼中有調(diào)用 */前面我們說了關(guān)于進(jìn)程的概念,屬性以及調(diào)度它的函數(shù).接下來我們講一下進(jìn)程的創(chuàng)立,進(jìn)程創(chuàng)立就是當(dāng)系統(tǒng)接收到一個(gè)要求創(chuàng)立進(jìn)程的信號(hào)時(shí),系統(tǒng)為新進(jìn)程所做的一系列工作.比方當(dāng)你在使用計(jì)算機(jī)上網(wǎng)的時(shí)候如果翻開了QQ聊天的效勞程序的話.當(dāng)你點(diǎn)擊QQ圖標(biāo)的時(shí)候,系統(tǒng)就接收到了一個(gè)創(chuàng)立QQ進(jìn)程的信號(hào),接下來系統(tǒng)就要做一系列的工作來完成這個(gè)過程,這就是我們下面要講的內(nèi)容: 根底創(chuàng)立.創(chuàng)立進(jìn)程的系統(tǒng)調(diào)用函數(shù)(系統(tǒng)調(diào)用是下一個(gè)要講的內(nèi)容)有

37、三個(gè),它們分別是: sys_fork(), sys_clone(), sys_vfork().由它們?nèi)齻€(gè)函數(shù)來完成進(jìn)程的創(chuàng)立,這三個(gè)函數(shù)都比擬簡(jiǎn)單,它們只是都同時(shí)調(diào)用了一個(gè)函數(shù)do_fork(),由于前面三個(gè)函數(shù)都比擬簡(jiǎn)單,我們?cè)诤竺嬷v,我們先講一下do_fork()函數(shù),這才是創(chuàng)立進(jìn)程的主體.它被前面三個(gè)函數(shù)調(diào)用int do_fork(unsigned long clone_flags, unsigned long stack_start, struct pt_regs, unsigned long stack_size) int retval = -ENOMEN; struct task_

38、struct *p; DECLARE_MUTEX_LOCKED(sem); if(clone_flags & CLONE_PID) if(current-pid) return -EPERM; /* 上面這段代碼的意思是: 如果clone_flags的CLONE_PID置位,那么除非是0號(hào)進(jìn)程否那么將返回錯(cuò)誤信息EPERM. clone_flags的定義將在后面介紹,0號(hào)進(jìn)程就是操作系統(tǒng)啟動(dòng)時(shí)創(chuàng)立的第一個(gè)進(jìn)程.上面的代碼中if(current-pid)要成立,除非是0號(hào)進(jìn)程.其中pid是進(jìn)程標(biāo)志符 */current-vfork_sem = &sem; p=alloc_task_struct(

39、);if(! p) goto fork_out;/ * 上面代碼的意思是: 申請(qǐng)一個(gè)新的內(nèi)存控制塊,其中alloc_task_struct是在/include中的宏定義: #define alloc_task_struct() (struct task_struct * ) _get_free_pages (GFP_KERNEL, 1)其中_get_free_pages是要申請(qǐng)兩個(gè)頁(yè)面,頁(yè)面是內(nèi)存管理的有關(guān)內(nèi)容,這兒大家只要一個(gè)頁(yè)面占4個(gè)字節(jié)就可以了.兩個(gè)頁(yè)面就是8個(gè)字節(jié),而大家查一下進(jìn)程控制塊的大小就可以知道它只有1600KB左右,有就時(shí)說它只有1M左右,那么還剩下將近的空間去有什么用呢?其

40、實(shí)剩余的空間是作為內(nèi)核??臻g.至于內(nèi)核棧的內(nèi)容以后會(huì)講到,但是如果申請(qǐng)內(nèi)存空間失敗那么直接棧道fork_out處執(zhí)行,fork_out在后面有定義 */*p = * current; / * 代碼意思: 前面申請(qǐng)了一個(gè)存放進(jìn)程控制塊的內(nèi)存空間,接下創(chuàng)立新進(jìn)程的進(jìn)程控制塊的內(nèi)容,具體做法是先直接將其父進(jìn)程的進(jìn)程控制塊的內(nèi)容復(fù)制過來,再在后面對(duì)需要更新的局部做一些必要的賦值 */retval= -EAGAIN; if(atomic_read(&p-user-processor) = p-rlimRLIMIT_NPROC. rlim_cur) goto bad_fork_free; atomic_i

41、nc(& p-user-_count); atomic_inc(& p-user-processes); /* 上面代碼的意思: 如果父親進(jìn)程已經(jīng)用了用戶進(jìn)程,那么修改p-user-_count和p-user-processes,將其數(shù)目加1,當(dāng)然除非用戶進(jìn)程的 RLIMIT_NPROC已經(jīng)超過額定數(shù)目,如果你對(duì)代碼不理解,那就先不要理解了,等你學(xué)完后面的代碼時(shí)就能理解了*/if(nr_threads = max_threads) goto bad_fork_cleanup_count; /* 上面的代碼的意思是: 如果計(jì)算機(jī)中的進(jìn)程的最大的進(jìn)程數(shù)大于系統(tǒng)限定的最大數(shù)目就返回錯(cuò)誤信號(hào) */ g

42、et_exec_domain(p-exec_domain); if(p-binfmt & p-binfmt-module)p-did_exec=NULL; p-swappable=NULL;p-state = TASK_UNINTERRUPTIBLE; / * 上面的代碼比擬簡(jiǎn)單: 其中p是指向進(jìn)程控制塊task_struct的指針,did_exec和swappable以及state都在進(jìn)程控制塊中有定義,是對(duì)進(jìn)程的這三個(gè)屬性進(jìn)行賦值,其意思如下: did_exec標(biāo)志的意思是: 此進(jìn)程是否被執(zhí)行. swappable標(biāo)志的意思是: 此進(jìn)程占有的內(nèi)存頁(yè)面是否可以被換出到交換空間. state在

43、前面有講過.那么上面代碼的意思是剛創(chuàng)立的進(jìn)程沒有被執(zhí)行并且內(nèi)存空間頁(yè)面不可以被換出內(nèi)存,當(dāng)前狀態(tài)設(shè)置為不可打斷睡眠狀態(tài) */ copy_flags(clone_flags, p); p-pid = get_pid(clone_flags); / * 上面代碼涉及到進(jìn)程控制塊中的進(jìn)程標(biāo)志flags,在 task_struct中有定義,flags的意思是進(jìn)程中有一些特殊的時(shí)候要靠它來決定進(jìn)程調(diào)度函數(shù)的調(diào)度,上面的意思是: 將傳進(jìn)來的參數(shù)clone_flags通過copy_flags()函數(shù)轉(zhuǎn)化為子進(jìn)程的進(jìn)程標(biāo)志flags, 然后為新的子進(jìn)程創(chuàng)立一個(gè)進(jìn)程標(biāo)志符pid */p-run_list.nex

44、t=NULL; p-run_list.prev=NULL; / * 對(duì)進(jìn)程隊(duì)列run_list進(jìn)行初始化,進(jìn)程隊(duì)列run_list以后將 */if(clone_flags & CLONG_VFORK) | ! (clone_flags & CLONG_PARENT) p-p_opptr = current; if(! (p-ptrace & PT_PTRACED) p-p_pptr = current; / * 前面我們說過創(chuàng)立新進(jìn)程的系統(tǒng)調(diào)用函數(shù)有三個(gè),分別是sys_fork,sys_vfork, sys_clone.上面的意思是: 如果使用的sys_vfork()函數(shù)調(diào)用創(chuàng)立函數(shù)或者傳人的

45、參數(shù)clone_flags的CLONE_PARENT位為1,那么將子進(jìn)程的的p_opptr()指針指向當(dāng)前進(jìn)程.其中p_opptr指針在進(jìn)程控制塊task_struct中有定義,意思是它指向進(jìn)程的祖先進(jìn)程.如果ptrace的PT_PTRACED不為1,那么將進(jìn)程的指向父進(jìn)程的指針指向當(dāng)前進(jìn)程.其中p_pptr是進(jìn)程指向其父親進(jìn)程的指針,同樣在進(jìn)程控制塊task_struct中有定義 * /p-p_cptr = NULL; / * 進(jìn)程的p_cptr指針指向它的兒子進(jìn)程,在這里初始化為NULL * /init_waitqueue_head(&p-wait_chldexit); / * 意思是:

46、初始化等待隊(duì)列,等待隊(duì)列是就緒隊(duì)列一個(gè)根底,等待隊(duì)列的進(jìn)程當(dāng)它得到它等待的資源(除CPU資源,CPUs是就緒隊(duì)列中的進(jìn)程等待的資源)后馬上進(jìn)入就緒隊(duì)列,等待調(diào)度函數(shù)的調(diào)用以獲得CPU資源 * / * 下面所以的代碼都是對(duì)進(jìn)程控制塊task_struct一些變量做一些初始化,這兒先就不過多的介紹了,現(xiàn)在只要知道有這些東西就行了 * /p-vfork_sem=NULL; spin_lock_inin(& p-alloc_lock);p-sigpending = 0;init_sigpending(& p-pending);p-it_real_value = p-it_virt_value =p-i

47、t_prof_value = 0;p-it_real_incr = p-it_virt_incr= p-it_prof_incr =0;init_timer(&p-real_timer);p-real_timer.data = (unsigned long) p ;p-leader = 0;p-tty_old_pgrd = 0;mes = 0;p-times.tms_cutime= p-times.tms_cstime = 0;# ifdef CONFIG_SMPint i;p-has_cpu = 0;p-proessor = current-proessor;for(i=0; ip-per_

48、cpu_utimei = p-per_cpu_stimei =0;spin_lock_init(& p-sigmask_lock); Endifp-lock_depth = -1;p-start_time = jiffies;/ * 初始化在此結(jié)束 */retval = -ENOMEN; if(copy_files(clone_flags, p)goto bad_fork_cleanup;if(copy_fs(clone_flags, p)goto bad_fork_cleanup_files;if(copy_sighand(clone_flags, p)goto bad_fork_clean

49、up_fs;if(copy_mm(clone_flags, p)goto bad_fork_cleanup_sighand;/ * 上面代碼的意思是: 根據(jù)傳人的參數(shù)clone_flags決定復(fù)制翻開文件表,文件系統(tǒng)信息,信號(hào)處理句柄和存儲(chǔ)信息管理(上面4個(gè)分別代表的信息)還是直接和父親進(jìn)程共享,僅僅將引用數(shù)加1 * / retval = copy_thread(0, clone_flags, stack_start, stack_size, p, reps);if(retval)goto bad_fork_cleanup_sighand;p-semundo = NULL;p-parent_e

50、xec_id = p-self_exec_id;p-swappable = 1;p-exit_signal = clone_flags & CSIGNAL;p-pdeath_signal = 0;p-counter = (current-counter +1) 1;/ * 將父親進(jìn)程的時(shí)間片加1再除2然后賦值給子進(jìn)程,同時(shí)將父親進(jìn)程的時(shí)間片減半 * /if(! current -counter)current-need_resched = 1;/ * 如果父親進(jìn)程的時(shí)間片減半后為0的話,直接將need_resched設(shè)置為1,need_resched在前面已經(jīng)說過,它的意思是: 如果設(shè)置為1,下一此調(diào)度函數(shù)可以直接調(diào)度這個(gè)進(jìn)程,但是如果設(shè)置為0那么表示下一次調(diào)度函數(shù)不能調(diào)度此函數(shù) */retval = pid; p-gpid = retval; INIT_LIST_HEAD(&p-thread_group); writh_lock_irq(

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝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)論