《計算機操作系統(tǒng) 》課件-3.3進程控制_第1頁
《計算機操作系統(tǒng) 》課件-3.3進程控制_第2頁
《計算機操作系統(tǒng) 》課件-3.3進程控制_第3頁
《計算機操作系統(tǒng) 》課件-3.3進程控制_第4頁
《計算機操作系統(tǒng) 》課件-3.3進程控制_第5頁
已閱讀5頁,還剩36頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

3.3進程控制原語(primitive):

由若干條指令構(gòu)成的“原子操作(atomicoperation)”過程,完成某種特定的功能,作為一個整體而不可分割--要么全都完成,要么全都不做。進程控制原語:(1)創(chuàng)建進程原語 (2)撤銷進程原語

(3)阻塞進程原語 (4)喚醒進程原語

進程創(chuàng)建進程撤銷進程阻塞與喚醒Linux進程管理253.3.1進程創(chuàng)建

1.進程圖:

描述進程家族關(guān)系的有向樹3.3進程控制ABCDHGFEIJK253.3.1進程創(chuàng)建

2.引起進程創(chuàng)建的典型事件3.3進程控制(1)作業(yè)調(diào)度(2)用戶登錄(3)提供特定服務(4)應用請求253.3.1進程創(chuàng)建

3.進程創(chuàng)建原語create(name,priority)

創(chuàng)建一個新進程,建立進程的PCB結(jié)構(gòu)并為其分配資源。3.3進程控制申請空閑PID申請空白PCB為新進程分配資源成功?成功?初始化PCB插入就緒隊列返回PID入口YY出錯出錯NN253.3.2進程撤銷

1.引起進程撤銷的典型事件3.3進程控制

進程正常運行結(jié)束而撤銷

進程異常終止而撤銷

進程應外界干預而終止:

操作員或操作系統(tǒng)干預父進程請求

父進程被撤銷3.3.2

進程撤銷由進程Pid獲得其PCB若進程處于運行態(tài),終止運行,設(shè)置重新調(diào)度標志若進程有子進程,遞歸撤銷子進程或為子進程指定新的父進程回收進程資源將進程移出所在隊列,待父進程收集其信息后,釋放PCB

2.進程撤銷過程kill(Pid):回收進程資源253.3.3進程阻塞與喚醒

1.引起進程阻塞和喚醒的典型事件3.3進程控制

當前進程請求資源失敗

當前進程需要等待某種操作的完成

當前進程的前驅(qū)進程尚未完成

當前進程無新工作可做3.3.3

進程阻塞與喚醒

2.進程阻塞過程:sleep()3.3進程控制入口保存進程CPU現(xiàn)場信息到PCB或堆棧中置進程狀態(tài)為“阻塞態(tài)”將進程PCB插入相應阻塞隊列中轉(zhuǎn)進程調(diào)度程序3.3.3

進程阻塞與喚醒3.進程喚醒:wakeup()3.3進程控制入口從阻塞隊列中確定喚醒進程置進程狀態(tài)為“就緒態(tài)”將進程PCB移出阻塞隊列并插入相應就緒隊列中3.3.4Linux進程管理3.3進程控制進程描述符task_struct進程創(chuàng)建do_fork()執(zhí)行程序exec()系列函數(shù)進程終止do_exit()等待子進程結(jié)束wait()進程睡眠wait_event*()進程喚醒wake_up()3.3.4Linux進程管理由三部分組成:進程控制塊(task_struct)正文段:進程要運行的程序代碼數(shù)據(jù)段:又分為用戶數(shù)據(jù)段和系統(tǒng)數(shù)據(jù)段

用戶數(shù)據(jù)段:進程在用戶態(tài)下執(zhí)行時直接操作的所有數(shù)據(jù),包括全部變量及用戶棧。

系統(tǒng)數(shù)據(jù)段:主要是內(nèi)核棧。保存中斷現(xiàn)場信息和進程在內(nèi)核態(tài)下執(zhí)行函數(shù)嵌套調(diào)用的返回現(xiàn)場信息。內(nèi)核棧的大小是靜態(tài)確定的,而用戶??梢栽谶M程運行時動態(tài)擴展1.Linux進程實體的組成:3.3進程控制3.3.4Linux進程管理進程狀態(tài):state,exit_state:見前面3.2.3節(jié)的介紹相關(guān)標識符信息:pid:進程標識符tgid:線程組領(lǐng)頭線程的PID,也是線程組所屬進程的PIDpgrp:進程所屬進程組的領(lǐng)頭進程的PIDuid和gid:進程的用戶ID及用戶組的IDeuid和egid:有效的uid和gid,當用戶使用“sudo”命令時,會暫時將root身份賦給euid和egid1.進程描述符task_struct()3.3進程控制進程狀態(tài)信息相關(guān)標識符信息進程家族關(guān)系進程調(diào)度相關(guān)信息地址空間及文件系統(tǒng)信息內(nèi)核堆棧及thread_info結(jié)構(gòu)信號處理相關(guān)信息時間及定時器信息3.3.4Linux進程管理進程家族關(guān)系:thread_group:指向該進程所在進程組中所有進程組成的鏈表real_parent:指向創(chuàng)建該進程的父進程parent:指向該進程的當前父進程children:指向該進程的子進程鏈表的頭部sibling:指向兄弟進程鏈表中的下一個或前一個節(jié)點1.進程描述符task_struct()3.3.4Linux進程管理進程調(diào)度相關(guān)信息:prio:進程的動態(tài)優(yōu)先級,取值范圍[0,139]static_prio:進程的靜態(tài)優(yōu)先級,取值范圍[0,139]normal_prio:常規(guī)動態(tài)優(yōu)先級rt_priority:實時進程優(yōu)先級,取值范圍[0,99]run_list:記錄進程在就緒隊列rq中的位置sched_class:進程所采用的調(diào)度器類1.進程描述符task_struct()stop_sched_class→dl_sched_class→rt_sched_class→fair_sched_class→idle_sched_classsched_entityse:普通進程調(diào)度實體

sched_rt_entityrt:實時進程調(diào)度實體policy:本進程采用的調(diào)度策略on_cpu:本進程當前由哪個CPU來運行

time_slice:進程的剩余時間片長度3.3.4Linux進程管理地址空間及文件系統(tǒng)信息:1.進程描述符task_struct()mm:進程用戶地址空間描述符active_mm:指向進程最近最常使用的地址空間fs:表示進程與文件系統(tǒng)的聯(lián)系

files:記錄進程當前打開的文件stack:指向進程內(nèi)核棧的指針16進程虛存管理數(shù)據(jù)結(jié)構(gòu)進程任務結(jié)構(gòu)task_struct*mm虛存區(qū)結(jié)構(gòu)vm_area_struct*vm_mmvm__startvm_end*vm_ops*vm_next頁目錄表pgd主存管理結(jié)構(gòu)mm_struct*mmap……*pgd封裝的操作集vm_operations_structopen()close()unmap()swapin()頁表PTE頁框PF(共享庫)進程虛擬主存虛擬主存段(0x40000000)(data)虛擬主存段(0x0804a020)(text)虛擬主存段(0x08048000)虛存區(qū)結(jié)構(gòu)vm_area_struct*vm_mmvm__startvm_end*vm_ops*vm_next虛存區(qū)結(jié)構(gòu)vm_area_struct*vm_mmvm__startvm_end*vm_ops*vm_next

…31current宏返回的是thread_info結(jié)構(gòu)task字段Task_struct1.進程描述符task_struct()內(nèi)核堆棧及thread_info結(jié)構(gòu):思考:為什么Linux要把最頻繁使用的thread_info結(jié)構(gòu)放在內(nèi)核棧的開始?31每個進程都有一個進程基本信息塊thread_info字段,描述當前進程運行的基本環(huán)境信息。structthread_info{

structtask_struct

*task;

structexec_domain

*exec_domain;/*當前進程可執(zhí)行程序的規(guī)范*/

unsignedlong

flags;

/*其中有TIF_NEED_RESCHED位*/

unsignedlong

status;structcpu_context_savecpu_context/*保存CPU上下文

*/

unsignedlongCPUint

preempt_count;

/*表示內(nèi)核能否被搶占。>0,內(nèi)核不能被搶占;=0,則表示內(nèi)核處于安全狀態(tài)(即沒有加鎖),可以搶占。mm_segment_t

addr_limit;

/*進程用戶空間上限

}1.進程描述符task_struct()內(nèi)核堆棧及thread_info結(jié)構(gòu):311.進程描述符task_struct()

進程信號處理相關(guān)信息:saved_sigmask:進程的信號掩碼,置位表示屏蔽signal:指向進程的信號描述符sighand:指向進程的信號處理程序描述符pending:記錄進程所有已經(jīng)觸發(fā)但是還沒有處理的信號

時間及定時器相關(guān)信息:utime,stime:進程在用戶態(tài)和內(nèi)核態(tài)的運行時間start_time:進程創(chuàng)建時間cutime:所有層次子進程在用戶態(tài)的運行時間總和cstime:所有層次子進程在核心態(tài)的運行時間總和3.3.4Linux進程管理2.進程創(chuàng)建3.3進程控制系統(tǒng)提供fork()、vfork()和clone()系統(tǒng)調(diào)用fork()、vfork()用來創(chuàng)建一般進程clone()功能強大,可以有選擇性的繼承父進程的資源,用來創(chuàng)建輕量級進程(線程)返回值:<0:

出錯,創(chuàng)建失敗=0:從子進程返回,即現(xiàn)在正執(zhí)行新創(chuàng)建的子進程>0:從父進程返回,即現(xiàn)在正執(zhí)行父進程,返回值為新創(chuàng)建的

子進程的PID2.進程創(chuàng)建fork():fork創(chuàng)造的子進程以copy_on_write技術(shù)復制父親進程的所有資源,父子進程使用同一代碼段,數(shù)據(jù)段和堆棧段,task_struct內(nèi)容也基本相同某共享數(shù)據(jù)頁面data:5子進程執(zhí)行:data=10新復制數(shù)據(jù)頁面data:5父進程使用子進程使用data:10intmain(){

intnum=1;

intchild;if(!(child=fork())){

printf("Thisisson,hisnumis:%d.andhispidis:%d\n",++num,getpid());}else{

printf("Thisisfather,hisnumis:%d,hispidis:%d\n",num,getpid());}}執(zhí)行結(jié)果為:Thisisson,hisnumis:2.andhispidis:2139

Thisisfather,hisnumis:1,hispidis:21382.進程創(chuàng)建fork():vfork()創(chuàng)建的子進程完全運行在父進程的地址空間上,子進程對虛擬地址空間任何數(shù)據(jù)的修改都為父進程所見

vfork()創(chuàng)建子進程后,父進程會被阻塞,直到子進程執(zhí)行exit()。2.進程創(chuàng)建vfork():某共享數(shù)據(jù)頁面data:5子進程執(zhí)行:data=10data:102.進程創(chuàng)建vfork():intmain(){

int

num=1;

intchild;if(!(child=vfork())){

printf("Thisisson,hisnumis:%d.andhispidis:%d\n",++num,getpid());}else{

printf("Thisisfather,hisnumis:%d,hispidis:%d\n",num,

getpid());}}運行結(jié)果為:Thisisson,hisnumis:2.andhispidis:4139

Thisisfather,hisnumis:2,hispidis:4138#include<unistd.h>

#include<stdio.h>Intmain(){fork();fork();putchar(’A’);}3.3.4Linux進程管理2.進程創(chuàng)建fork()使用舉例:#include<unistd.h>

#include<stdio.h>Intmain(){ fork();fork();fork();putchar(‘A’);}例:main(){intx;while((x=fork())==-1);if(x==0)printf(“a”);elseprintf(“b”);

printf(“c”);}abcc①bcac②abcc③acbc④cabc⑤結(jié)果?702.進程創(chuàng)建fork()使用舉例:小組討論:寫出可能的執(zhí)行結(jié)果main(){intchild,i=2;if((child=fork())==–1){printf("forkerror.");exit();}if(child==0){i=i+3;printf(“i=%d\n”,i);}i=i+5;printf(“i=%d\n”,i);}1.forkerror2.i=5i=10i=73.i=7i=5i=104.i=5i=7i=10插入else呢?712.進程創(chuàng)建設(shè)置新進程的跟蹤狀態(tài)完成進程創(chuàng)建的主要工作2.進程創(chuàng)建do_fork()解析:根據(jù)clone_flags的值作相應處理copy_process()

創(chuàng)建子進程描述符及所有其他的內(nèi)核數(shù)據(jù)結(jié)構(gòu)為新進程創(chuàng)建一個內(nèi)核棧、thread_info和task_struct,

這里完全copy父進程的內(nèi)容,所以到目前為止,

父進程和子進程是沒有任何區(qū)別的task_struct中ftrace_ret_stack結(jié)構(gòu)的初始化,即函數(shù)返回用的棧,或稱用戶棧Task_struct中互斥變量的初始化p

=

dup_task_struct(current);

if

(!p)

goto

fork_out;

ftrace_graph_init_task(p);

rt_mutex_init_task(p);

if

(atomic_read(&p->real_cred->user->processes)

>=

p->signal->rlim[RLIMIT_NPROC].rlim_cur)

{

if

(!capable(CAP_SYS_ADMIN)

&&

!capable(CAP_SYS_RESOURCE)

&&p->real_cred->user

!=

INIT_USER)

goto

bad_fork_free;

}

檢查進程資源限制、用戶擁有進程數(shù)量限制等,若超過限制,則出錯返回2.進程創(chuàng)建do_fork()解析:Task_struct中一些成員被清0或設(shè)置為初始值,大多數(shù)數(shù)據(jù)共享一組統(tǒng)計信息的初始化代碼:if

(nr_threads

>=

max_threads)

goto

bad_fork_cleanup_count;

檢查創(chuàng)建的進程是否超過了系統(tǒng)進程總量sched_fork(p,

clone_flags);

設(shè)置子進程調(diào)度信息:運行CPU、建立調(diào)度實體初始時間片長度、優(yōu)先級、狀態(tài)置為TASK_RUNNINGcopy_flags(clone_flags,

p);copy_semundo():copy_files(clone_flags,

p)copy_fs(clone_flags,

p)copy_signal(clone_flags,

p)copy_mm(clone_flags,

p)copy_namespaces一組復制父進程信息的代碼:

copy_process()2.進程創(chuàng)建do_fork()解析:copy_thread(clone_flags,

stack_start,

stack_size,

p,

regs)復制父進程的內(nèi)核棧,并置棧中的eax=0pid

=

alloc_pid(p->nsproxy->pid_ns);完成一些掃尾工作并返回新進程的task_struct結(jié)構(gòu)的指針

分配一個有效PID①do_fork()函數(shù)的第一個參數(shù)clone_flags可由多個標志位組成:

CLONE_VM父子進程共享進程空間;CLONE_FS父子進程共享文件系統(tǒng)信息;CLONE_FILES父子進程共享打開的文件;CLONE_VFORK如果父進程想使子進程終止時喚醒它,則置該位。

CLONE_SIGHAND父子進程共享信號處理函數(shù)表

CLONE_PTRACE如果父進程被跟蹤的話,那么子進程也被跟蹤。3.3.4Linux進程管理2.進程創(chuàng)建do_fork()幾點說明:②

寫時拷貝:在創(chuàng)建新進程時內(nèi)核不復制父進程的整個地址空間,而是讓父進程和子進程以讀方式共享同一拷貝只有當一方真正需要寫入時,數(shù)據(jù)才被復制,這時,父子進程才擁有各自的拷貝execl(),execle(),execlp(),execv(),

execvp()功能:將一個指定的可執(zhí)行程序裝入調(diào)用它的進程映像中,并覆蓋調(diào)用進程的程序空間。處理過程:根據(jù)給出的路徑名找到指定文件,檢查該文件是否可執(zhí)行,用戶是否具有執(zhí)行權(quán)限。將該文件載入到調(diào)用它的進程映像中并覆蓋其原來的程序。為該程序的執(zhí)行設(shè)置參數(shù)組和環(huán)境變量。啟動該進程進入新的程序入口點去執(zhí)行。3.3.4Linux進程管理3.Exec:執(zhí)行文件,啟動新程序運行調(diào)用格式:exec(文件名,參數(shù)表,環(huán)境變量表)

#include<stdio.h>#include<unistd.h>intmain(){if(fork()==0){printf("thisischildstart\n");printf("a\n");execlp("./file1","file1",NULL);printf("b\n");printf("thisischildend\n");}printf("c\n");}file1:#include<stdio.h>main(){

printf(”d”);}733.Exec:執(zhí)行文件,啟動新程序運行3.3.4Linux進程管理排除一些無效的特殊情況設(shè)置task_struct中flags的PF_EXITING標志,表示正在被終止;分別調(diào)用:exit_mm(),exit_sem(),__exit_files(),__exit_fs(),exit_stack_usage(),exit_thread(),釋放相關(guān)資源;如果進程有子進程,則讓同組其他進程或init進程作為其所有子進程的父進程。設(shè)置task_struct的exit_code為終止代碼,供父進程檢索;把進程狀態(tài)置為僵死狀態(tài)TASK_ZOMBIE。并向其原父進程發(fā)送SIGCHILD信號,通知其某個子進程已經(jīng)終止。最后將進程狀態(tài)設(shè)置為TASK_DEAD,并轉(zhuǎn)schedule()

重新進行調(diào)度。4.進程終止3.3.4Linux進程管理exit()系統(tǒng)調(diào)用:do_exit()處理過程:

立即阻塞調(diào)用進程,等待一個子進程的終止。調(diào)用進程被一個終止的子進程喚醒,搜集該子進程信息,如運行時間等;調(diào)用release_task(),釋放該子進程的內(nèi)核棧、task_struct結(jié)構(gòu)5.wait()系統(tǒng)調(diào)用3.3.4Linux進程管理pid_twait(int*status)參數(shù)status:存放子進程的退出碼,即從子進程的main函數(shù)返回的值或子進程中exit()函數(shù)的參數(shù)處理過程:

例:/*zombie.c*/#include<sys/type.h>#include<sys/wait.h>#include<unistd.h>#include<stdlib.h>main(){ pid_tpid;

pid=fork(); if(pid<0) printf("erroroccurred!\n"); elseif(pid==0)/*如果是子進程*/ exit(0);else /*如果是父進程*/sleep(60); /*休眠60秒*/wait(NULL);/*收集僵尸進程*/}編譯并運行:$gcczombie.c-ozombie$./zombie&[1]1577$ps-ax ......

1177pts/0S0:00-bash1577pts/0S0:00./zombie1578pts/0Z0:00[zombie]1579pts/0R0:00ps-axS:可中斷睡眠;Z:僵死;R:運行5.wait()系統(tǒng)調(diào)用隊列相關(guān)數(shù)據(jù)結(jié)構(gòu):等待隊列頭:

struct__wait_queue_head{

spinlock_tlock;//實現(xiàn)對等待隊列的互斥

structlist_headtask_list;

}

typedefstr

溫馨提示

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

評論

0/150

提交評論