操作系統(tǒng)進程管理課程設計報告_第1頁
操作系統(tǒng)進程管理課程設計報告_第2頁
操作系統(tǒng)進程管理課程設計報告_第3頁
操作系統(tǒng)進程管理課程設計報告_第4頁
操作系統(tǒng)進程管理課程設計報告_第5頁
已閱讀5頁,還剩11頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

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

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

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

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

5、線性空間地址; 0-0 xFFFFFFFF 為內核線性空間地址 */struct exec_domain *exec_domain; volatile long need_resched; unsigned long ptrace; int lock_depth; long counter; /* 進程的動態(tài)優(yōu)先級,在代碼后面有說明 */long nice; /* 進程的靜態(tài)優(yōu)先級,在代碼后面有說明 */unsigned long policy; /* 進程采用的調度策略,在代碼后面有說明 */struct mm_struct *mm; /* 進程屬性中指向內存管理的數(shù)據(jù)結構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; /* 所以進程通過這兩個指針組成一個雙向鏈表*/struct mm_struct *active_mm; /* 指向活動地址空間,在后面的代碼有說明 */ /* 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; /* 進程標志符,在代碼后面有說明 */pid_t pgrp; /* 進程組標號,在代碼后面有說明 */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; /* 這五個標志表示一個進程的在計算

8、機中的親屬關系,分別標志祖先進程,父進程,子進程,弟進程和兄進程,為了在兩個進程之間共享方便而設立 */struct list_head thread_group; struct task_struct *pidhist_next; struct task_struct *pidhist_pprev; /* 上面兩個指針是為了在計算機中快速查一個進程而設立,具體方式以后講*/wait_queue_head_t wait_chldexit; struct completion *vfork_sem; unsigned long rt_priority; /* 實時進程的優(yōu)先級標志*/ 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; /* 進程屬性中指向和文件管理有關的數(shù)據(jù)結構*/ 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 定義了進程的狀態(tài),進程總共有6種狀態(tài)標志,分別是:一. TASK_RUNING. (正在運行狀態(tài)或者是可運行狀態(tài))二. TASK_INTERRUPTIBLE,(可打斷睡眠狀態(tài))三. TASK_UNINTERRUPTIBLE,(不可打斷睡眠狀態(tài))四. TASK_ZOMBLE. (僵死狀態(tài))五. TAKS_STOPPED.(暫停狀態(tài))六. 交換狀態(tài).這六種屬性標志了此進程現(xiàn)在的狀態(tài),各種不同的狀態(tài)決定了進程什么時候獲得CPU而被執(zhí)行.正在運行狀態(tài)是當前正在運行進程的狀態(tài).也就是說他的volatile long state被標志成TASK_RUANING.可運

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

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

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

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

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

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

20、種狀態(tài)存在,這在進程的屬性里已經(jīng)有了介紹,其中存在于就緒隊列TASK_RUNNING中處于運行狀態(tài)的進程是等待計算機中唯一的資源CPU的進程,它們只要一得到CPU就馬上可以被執(zhí)行,那么操作系統(tǒng)是安什么樣的規(guī)那么來讓這些進程合理和公平的得到CPU的呢,這就要用到計算機的調度函數(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指當前進程,當前進程所指的內存空間如果為空,那么進程必定有問題,出錯返回 */need_resched_back: prev=current; this_cpu=prev-processor; if(in_interrupt() goto scheduling_in_interrupt; /*上面代碼的意思是: 將局部變量prev和this_cpu初始化為當前進程和當前CPU.然后檢查schedule()是否中斷調用,假設是那么直接返回,其中goto后面的轉到的地方在本程序中有定義,比方本進程后面的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; /* 檢查是否有軟中斷請求,軟中斷softirq將在后面講解 */hand_softirp_back: sched_data= & aligned_datathis_cpu.schedule_data; spin_lock_irp(&r

23、unqueue_lock);/* 局部變量sched_data中保存當前進程的數(shù)據(jù)區(qū),*/ if(prev-policy = SCHED_RR) goto move_rr_last;* 當前基于優(yōu)先權輪轉法的調度策略實時進程,如果要調用它,先檢查其count是否0假設是,那么將其掛到運行隊列的最后面.具體做法在后面的 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; /* 上面這段代碼意思是: 如果進程的狀態(tài)為可中斷睡眠狀態(tài)且喚醒它的信號正在迫近,那么將其置為可運行狀態(tài),如果狀態(tài)為運行狀態(tài)那么忽略,如果狀態(tài)除上述兩種之外的其它狀態(tài)那么直接刪除.最后將neet_resched置為0,neet_resched置0意味著本能啟動調度函數(shù)shchedule(); */repeat_schedule: next = idlt_task(this_cpu); c = -1000; if(prev-state = TASK_RUNNING

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

26、odness值賦予goodness優(yōu)先級變量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; /* 上面代碼的意思是: 遍歷整個就緒隊列,計算出每一個進程的goodness權值并且與當前進程做比擬,選擇goodness

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

28、; /* 意思為: 將調度數(shù)據(jù)區(qū)指針指向下一個要調度的進程并將當前進程的cpu設置為下一個進程的當前cpu. */#endifspin_unlock_irq(&runqueue_lock);if(prev = next) goto same_processor; /* 意思為: 如果當前運行的進程的goodness還是隊列中所以進程中最高的,也就是說下一個要調度的進程還是當前進程.那么只要重新得到cpu控制權返回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); /* 上面的代碼是進行進程切換 */* 下面的代碼是前面代碼中goto要轉到的地方 */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();在上面的我們說了進程調度程序schedule(),接著說一下上面的函數(shù)中用到的進程優(yōu)先級的權值的運行

33、函數(shù)googness();這個函數(shù)的作用很簡單,就是算出就緒隊列中的進程的優(yōu)先級,然后調度程序調度優(yōu)先級最高的進程獲得當前CPU,計算機中進程分為兩種,一為普通進程,它的優(yōu)先級用進程控制塊中的counter表示,二為實時進程,實時進程的優(yōu)先級用rt_priority表示,它在進程控制塊中有定義,當就緒隊列中同時存在兩種進程的時候,實時進程總是先于普通進程運行,它的實現(xiàn)機制是實時進程的權值以1000做為根底值,也就是說實時進程的權值是1000加上它的進程優(yōu)先級,而普通進程的優(yōu)先級就是它的進程優(yōu)先級.整個函數(shù)比擬簡單,但卻是操作系統(tǒng)內核最為頻繁調用的函數(shù)之一,也直接關系到操作系統(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ù)返回的權值weight并進行初始化 */* 下面是普通進程的處理情況 */ if(p-* & SCHED_YIELD) goto out; / * 如果要放棄本次調度,那么直接返回, 轉到的out處在后面有定義 */ if(p-policy = SCHED_OTHER) weight = p- counter;if(!weight) goto ou

35、t; /* 函數(shù)是普通進程的情況,在這種情況下,進程的權值直接為本進程的剩余時間,如果剩余時間不存在或為0,那么直接返回 */#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; /* 下面是實時進程的處理情況 */ weight = 1000 + p-re_priority;/* 實時進程的權值至少為1000,也就說它的權值是它是基數(shù)1000加上實時

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

37、三個,它們分別是: sys_fork(), sys_clone(), sys_vfork().由它們三個函數(shù)來完成進程的創(chuàng)立,這三個函數(shù)都比擬簡單,它們只是都同時調用了一個函數(shù)do_fork(),由于前面三個函數(shù)都比擬簡單,我們在后面講,我們先講一下do_fork()函數(shù),這才是創(chuàng)立進程的主體.它被前面三個函數(shù)調用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號進程否那么將返回錯誤信息EPERM. clone_flags的定義將在后面介紹,0號進程就是操作系統(tǒng)啟動時創(chuàng)立的第一個進程.上面的代碼中if(current-pid)要成立,除非是0號進程.其中pid是進程標志符 */current-vfork_sem = &sem; p=alloc_task_struct(

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

40、實剩余的空間是作為內核??臻g.至于內核棧的內容以后會講到,但是如果申請內存空間失敗那么直接棧道fork_out處執(zhí)行,fork_out在后面有定義 */*p = * current; / * 代碼意思: 前面申請了一個存放進程控制塊的內存空間,接下創(chuàng)立新進程的進程控制塊的內容,具體做法是先直接將其父進程的進程控制塊的內容復制過來,再在后面對需要更新的局部做一些必要的賦值 */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īng)用了用戶進程,那么修改p-user-_count和p-user-processes,將其數(shù)目加1,當然除非用戶進程的 RLIMIT_NPROC已經(jīng)超過額定數(shù)目,如果你對代碼不理解,那就先不要理解了,等你學完后面的代碼時就能理解了*/if(nr_threads = max_threads) goto bad_fork_cleanup_count; /* 上面的代碼的意思是: 如果計算機中的進程的最大的進程數(shù)大于系統(tǒng)限定的最大數(shù)目就返回錯誤信號 */ 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; / * 上面的代碼比擬簡單: 其中p是指向進程控制塊task_struct的指針,did_exec和swappable以及state都在進程控制塊中有定義,是對進程的這三個屬性進行賦值,其意思如下: did_exec標志的意思是: 此進程是否被執(zhí)行. swappable標志的意思是: 此進程占有的內存頁面是否可以被換出到交換空間. state在

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

44、t=NULL; p-run_list.prev=NULL; / * 對進程隊列run_list進行初始化,進程隊列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)立新進程的系統(tǒng)調用函數(shù)有三個,分別是sys_fork,sys_vfork, sys_clone.上面的意思是: 如果使用的sys_vfork()函數(shù)調用創(chuàng)立函數(shù)或者傳人的

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

46、初始化等待隊列,等待隊列是就緒隊列一個根底,等待隊列的進程當它得到它等待的資源(除CPU資源,CPUs是就緒隊列中的進程等待的資源)后馬上進入就緒隊列,等待調度函數(shù)的調用以獲得CPU資源 * / * 下面所以的代碼都是對進程控制塊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;/ * 初始化在此結束 */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決定復制翻開文件表,文件系統(tǒng)信息,信號處理句柄和存儲信息管理(上面4個分別代表的信息)還是直接和父親進程共享,僅僅將引用數(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;/ * 將父親進程的時間片加1再除2然后賦值給子進程,同時將父親進程的時間片減半 * /if(! current -counter)current-need_resched = 1;/ * 如果父親進程的時間片減半后為0的話,直接將need_resched設置為1,need_resched在前面已經(jīng)說過,它的意思是: 如果設置為1,下一此調度函數(shù)可以直接調度這個進程,但是如果設置為0那么表示下一次調度函數(shù)不能調度此函數(shù) */retval = pid; p-gpid = retval; INIT_LIST_HEAD(&p-thread_group); writh_lock_irq(

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論