日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

高级操作系统——XV6进程管理

發(fā)布時(shí)間:2023/12/9 windows 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 高级操作系统——XV6进程管理 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

源代碼閱讀:
type.h:用于聲明一些數(shù)據(jù)類型的簡化名稱,和聲明頁表指針的數(shù)據(jù)類型。
param.h:主要用于聲明基本的一些常量,包括內(nèi)核棧大小等。
memlayout.h:主要用于聲明一些和內(nèi)存與地址相關(guān)的常量與方法,包括虛擬內(nèi)存轉(zhuǎn)物理內(nèi)存的方法以及物理內(nèi)存轉(zhuǎn)虛擬內(nèi)存的方法等。
defs.h:聲明在之后文件中要用到的函數(shù)。
x86.h:讓c代碼使用特殊的x86匯編的一些函數(shù)包括outb等,并聲明trapframe。
asm.h:一些匯編上的宏定義
mmu.h:定義x86內(nèi)存管理單元,包括控制寄存器CR上的不同位代表的含義。
elf.hELF:可執(zhí)行文件的格式,包括ELF頭的數(shù)據(jù)結(jié)構(gòu)等。
vm.c:一些cpu虛擬內(nèi)存管理的函數(shù)
proc.h:聲明了CPU在內(nèi)核中的數(shù)據(jù)結(jié)構(gòu)表示struct cpu,進(jìn)程在內(nèi)核中的數(shù)據(jù)結(jié)構(gòu)struct proc,上下文在內(nèi)核中的數(shù)據(jù)結(jié)構(gòu)struct context。
swtch.S聲明用于上下文切換的swtch函數(shù),匯編語言生成
kalloc.c聲明一些物理內(nèi)存分配的函數(shù),包括分配的kalloc()和用于free的kfree()。

Proc.c:
Ptable:進(jìn)程索引表
Nextpid:進(jìn)程的ID
Allocproc:分配進(jìn)程的內(nèi)核棧和一些寄存器,將進(jìn)程狀態(tài)UNUSED改寫為EMBRYO
Userinit:第一個(gè)進(jìn)程的初始化操作
Growproc:增加或者減少所占用的內(nèi)存空間
Fork():創(chuàng)建進(jìn)程
Exit():退出當(dāng)前進(jìn)程,并將其父進(jìn)程喚醒
Wait();等待子進(jìn)程退出的
scheduler():內(nèi)核運(yùn)行時(shí)用于進(jìn)程調(diào)度的循環(huán)
sched():切換到內(nèi)核的
yield():放棄cpu占用
sleep();換成SLEEPING狀態(tài),并通過chan標(biāo)志進(jìn)程
wakeup();喚醒chan上所有的進(jìn)程
kill():殺死進(jìn)程
procdump;向控制臺上打印當(dāng)前進(jìn)程狀態(tài)的

(一) 什么是進(jìn)程,什么是線程?操作系統(tǒng)的資源分配單位和調(diào)度單位分別是什么?XV6 中的
進(jìn)程和線程分別是什么,都實(shí)現(xiàn)了嗎?
答案:
(1)什么是進(jìn)程:
1:操作系統(tǒng)由單道處理轉(zhuǎn)向多道處理,傳統(tǒng)的靜態(tài)程序已經(jīng)不能描述執(zhí)行的并發(fā)性,所以由動態(tài)的進(jìn)程對多道并發(fā)進(jìn)行描述。
2:進(jìn)程是程序,數(shù)據(jù),程序控制塊的集合
(2)什么是線程:
(3):進(jìn)程占用空間多,切換時(shí)空消耗大。而為了降低時(shí)空消耗,引入了線程
引入線程前:資源分配單位和調(diào)度為進(jìn)程
引入線程后:資源分配的單位是進(jìn)程,調(diào)度的單位是線程
(4)XV6中只實(shí)現(xiàn)了進(jìn)程proc,具體內(nèi)容在proc.c中

(二) 進(jìn)程管理的數(shù)據(jù)結(jié)構(gòu)是什么?在 Windows,Linux,XV6 中分別叫什么名字?其中包含哪些內(nèi)容?操作系統(tǒng)是如何進(jìn)行管理進(jìn)程管理數(shù)據(jù)結(jié)構(gòu)的?它們是如何初始化的?
(1):進(jìn)程管理的數(shù)據(jù)結(jié)構(gòu)是進(jìn)程控制塊。
(2):Linux:task_struct
Windows:EPROCESS、KPROCESS、PEB
XV6:proc .h,proc.c
(3):包含 進(jìn)程描述信息,進(jìn)程控制信息,所擁有的資源和使用情況,CPU現(xiàn)場信息
1:Linux下為/include/linux/sched.h內(nèi)部的struct task_struct,其中包括管理進(jìn)程所需的各種信息。創(chuàng)建一個(gè)新進(jìn)程時(shí),系統(tǒng)在內(nèi)存中申請一個(gè)空的task_struct ,并填入所需信息。同時(shí)將指向該結(jié)構(gòu)的指針填入到task[]數(shù)組中。
2:Windows下?lián)碛袃蓚€(gè)相關(guān)的對象,EPROCESS(執(zhí)行體進(jìn)程對象) KPROCESS(內(nèi)核進(jìn)程對象 )其中KPROCESS又稱為PCB
EPEOCESS位于內(nèi)核層之上它側(cè)重于提供各種管理策略,同時(shí)為上層應(yīng)用程序提供基本的功能接口。所以,在執(zhí)行體層的進(jìn)程和線程數(shù)據(jù)結(jié)構(gòu)中,有些成員直接對應(yīng)于上層應(yīng)用程序中所看到的功能實(shí)體。
KPROCESS結(jié)構(gòu)體位于內(nèi)核層,存儲著進(jìn)程的必要信息

3:XV6下在proc .h內(nèi)聲明,包括進(jìn)程 ID ,進(jìn)程狀態(tài) ,父進(jìn)程,context,cpu記錄了內(nèi)存地址和棧指針等
xv6的PCB就是proc.h中的proc結(jié)構(gòu)體。其內(nèi)容包括:
uint sz:進(jìn)程的內(nèi)存空間大小。
pde_t* pgdir:進(jìn)程的頁表。
char *kstack:進(jìn)程的內(nèi)核棧指針
enum procstate state:進(jìn)程的狀態(tài)(包括六種UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE)
int pid:進(jìn)程的pid
struct proc *parent:進(jìn)程的父進(jìn)程指針。
struct trapframe *tf:位于x86.h,是中斷進(jìn)程后,需要恢復(fù)進(jìn)程繼續(xù)執(zhí)行所保存的寄存器內(nèi)容。
struct context *context:切換進(jìn)程所需要保存的進(jìn)程狀態(tài)。切換進(jìn)程需要維護(hù)的寄存器內(nèi)容,定義在proc.h中。
void *chan:不為0時(shí),保存該進(jìn)程睡眠時(shí)的隊(duì)列。
int killed:不為0時(shí),則該進(jìn)程被殺死。
struct file *ofile[NOFILE]:打開文件的組。
struct inode *cwd:進(jìn)程當(dāng)前的目錄。
char name[16]:進(jìn)程名。
(4):Xv6通過數(shù)據(jù)結(jié)構(gòu)ptable對進(jìn)程進(jìn)行管理,代碼如下:
struct {
struct spinlock lock;
struct proc proc[NPROC];
} ptable;
(5):Xv6的初始化操作:
1:第一個(gè)進(jìn)程初始化:自舉程序bootmain.c,調(diào)用主方法main.c,調(diào)用proc.c中的userinit()建立
2:第一個(gè)用戶進(jìn)程(分配了一個(gè)物理頁,并將這個(gè)物理地址頁映射到虛擬地址為0處,將原來的加載到物理地址為0處的initcode.S的代碼加載到這個(gè)虛擬地址對應(yīng)的物理頁中。另外還設(shè)置進(jìn)程的trapframe,以便能從內(nèi)核態(tài)返回到用戶態(tài))
3:之后的進(jìn)程初始化:調(diào)用fork()
4:無論是userinit()還是fork()都會調(diào)用allocproc()函數(shù)
5:allocproc的工作是在頁表中分配一個(gè)槽(即結(jié)構(gòu)體 struct proc),并初始化進(jìn)程的狀態(tài),為其內(nèi)核線程的運(yùn)行做準(zhǔn)備。簡而言之,即設(shè)置好一個(gè)特別準(zhǔn)備的內(nèi)核棧和一系列內(nèi)核寄存器,并將進(jìn)程狀態(tài)由UNUSED改寫為EMBRYO

(三) 進(jìn)程有哪些狀態(tài)?請畫出 XV6 的進(jìn)程狀態(tài)轉(zhuǎn)化圖。在 Linux,XV6 中,進(jìn)程的狀態(tài)分別 包括哪些?你認(rèn)為操作系統(tǒng)的設(shè)計(jì)者為什么會有這樣的設(shè)計(jì)思路?
(1):進(jìn)程狀態(tài)分別有:UNUSED,EMBRYO,RUNNABLE,RUNNING,SLEEPING,ZOMBIE
1:UNUSED:進(jìn)程的初始化狀態(tài)(enum枚舉特性決定)
2:fork()或者userinit()中調(diào)用allocproc()即分配內(nèi)核棧后改為EMBRYO
3:fork()或者userinit()進(jìn)行一系列初始化操作后改為RUNNABLE
4:scheduler()會一直執(zhí)行選擇進(jìn)程改為RUNNING,進(jìn)程調(diào)用yield()改為RUNNABLE, 調(diào)用sleep()改為SLEEPING,而wakeup()由SLEEPING改為RUNNABLE
5:程序調(diào)用exit()和wait()會將其變?yōu)閆OMBIE

(2):Linux進(jìn)程狀態(tài):創(chuàng)建,就緒,執(zhí)行,阻塞,就緒掛起,阻塞掛起,結(jié)束

(3):提高CPU的利用率,增加并發(fā)能力

(四) 如何啟動多進(jìn)程(創(chuàng)建子進(jìn)程)?如何調(diào)度多進(jìn)程?調(diào)度算法有哪些?操作系統(tǒng)為何要 限制一個(gè) CPU 最大支持的進(jìn)程數(shù)?XV6 中的最大進(jìn)程數(shù)是多少?如何執(zhí)行進(jìn)程的切換?什么是進(jìn)程上下文?多進(jìn)程和多 CPU 有什么關(guān)系?

(1):利用操作系統(tǒng)創(chuàng)建或者父進(jìn)程創(chuàng)建,在xv6中,第一個(gè)進(jìn)程是由Userinit()創(chuàng)建初始化,之后通過fork()創(chuàng)建初始化

(2):利用調(diào)度算法進(jìn)行調(diào)度

(3):先來先服務(wù),短作業(yè)先服務(wù),時(shí)間片輪轉(zhuǎn)發(fā),優(yōu)先級調(diào)度法,多級反饋輪轉(zhuǎn)法,高響應(yīng)比優(yōu)先法

(4):一是考慮內(nèi)存空間,進(jìn)程數(shù)量過多占用大量內(nèi)存 二是增加了缺頁中斷的可能性,會導(dǎo)致cpu不斷的執(zhí)行頁面換入換出,浪費(fèi)大量時(shí)間

(5):XV6的最大進(jìn)程數(shù)見param.h文件中的#define NPROC 64,最大64;
#define NPROC 64 // maximum number of processes

(6):切換上下文:
1:當(dāng)前進(jìn)程通過調(diào)用yield()(可能是時(shí)間片用完),進(jìn)行進(jìn)程切換。yield函數(shù)調(diào)用sched函數(shù),sched函數(shù)啟動switch函數(shù)完成進(jìn)程切換,而switch又會觸發(fā)scheduler(void),scheduler(void)中會選擇一個(gè)進(jìn)程切換上下文,仍調(diào)用swtch(&cpu->scheduler, proc->context);
2:整個(gè)流程是這樣的:yield->sched->switch->scheduler->switch
3:其中switch的函數(shù)原型void swtch(struct context **old, struct context *new);
4:它的工作主要包括:1. 保存當(dāng)前(old)進(jìn)程的上下文。 2. 加載新進(jìn)程(new)的上下文到機(jī)器寄存器中。可以理解為是匯編實(shí)現(xiàn)

(7):進(jìn)程運(yùn)行時(shí),其硬件狀態(tài)保存在CPU 上的寄存器中,寄存器:程序計(jì)數(shù)器、程序狀態(tài)寄存器、棧指針、通用寄存器、其他控制寄存器的值。進(jìn)程不運(yùn)行時(shí),這些寄存器的值保存在PCB 中。將CPU 硬件狀態(tài)從一個(gè)進(jìn)程換到另一個(gè)進(jìn)程的過程稱為
上下文切換

(8):沒有必然聯(lián)系。一個(gè)CPU在某一時(shí)刻只能運(yùn)行一個(gè)進(jìn)程,宏觀上并行,微觀上串行。而多個(gè)CPU可以同時(shí)運(yùn)行多個(gè)程序

(五) 內(nèi)核態(tài)進(jìn)程是什么?用戶態(tài)進(jìn)程是什么?它們有什么區(qū)別?
(1):系統(tǒng)分為內(nèi)核態(tài)和用戶態(tài)。在內(nèi)核里產(chǎn)生的進(jìn)程稱為內(nèi)核級進(jìn)程,在用戶態(tài)上產(chǎn)生的進(jìn)程稱為用戶態(tài)進(jìn)程。
(2)區(qū)別:
1)運(yùn)行在不同的系統(tǒng)狀態(tài),用戶態(tài)進(jìn)程執(zhí)行在用戶態(tài),內(nèi)核態(tài)進(jìn)程執(zhí)行在內(nèi)核態(tài)
2)進(jìn)入方式不同,用戶態(tài)進(jìn)程可直接進(jìn)入,內(nèi)核態(tài)必須通過運(yùn)行系統(tǒng)調(diào)用命令
3)返回方式不同,用戶態(tài)進(jìn)程直接返回,內(nèi)核態(tài)進(jìn)程有重新調(diào)度過程
4)內(nèi)核態(tài)進(jìn)程優(yōu)先級要高于用戶態(tài)進(jìn)程,并且內(nèi)核態(tài)進(jìn)程特權(quán)級別最高,它可以執(zhí)行系統(tǒng)級別的代碼
聯(lián)系:
用戶級進(jìn)程和內(nèi)核級進(jìn)程存在一對一,多對一,多對多的關(guān)系

(六) 首先看一個(gè)簡略的進(jìn)程在內(nèi)存中的布局

再看一個(gè)詳細(xì)的部分

在內(nèi)存中分為五部分:
(1)代碼區(qū)(Code segment):存放程序的二進(jìn)制代碼文件
(2)常量區(qū)(Constant segment):所有常量均存放在常量區(qū)。程序結(jié)束后由OS釋放通常是字符串常量
(3)全局?jǐn)?shù)據(jù)區(qū)(Global data segment):全局變量和靜態(tài)數(shù)據(jù),函數(shù)內(nèi)部的靜態(tài)局部變量。程序結(jié)束有OS釋放
(4)堆區(qū)(Heap segment):new,malloc產(chǎn)生的動態(tài)數(shù)據(jù)。由程序員分配和釋放 一般一個(gè)new就要對應(yīng)一個(gè)delete
有時(shí)候堆區(qū)又分為 自由存儲區(qū),就是那些由malloc等分配的內(nèi)存塊,他和堆是十分相似的,不過它是用free來結(jié)束自己的生命的。
(5)棧區(qū)(Stack segment):局部變量,函數(shù)參數(shù)。由編譯器自動分配和釋放
一個(gè)例子,大概介紹各個(gè)常量和變量的對應(yīng)區(qū)關(guān)系
//main.cpp
int a = 0; 全局初始化區(qū)
char *p1; 全局未初始化區(qū)
main()
{
int b; 棧
char s[] = “123”; 棧
char *p2 = “abcdefg”;abcdefg\0在常量區(qū),p3在棧上。
char *p3; 棧
static int c =0; 全局(靜態(tài))初始化區(qū)
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得來得10和20字節(jié)的區(qū)域就在堆區(qū)。
strcpy(p1, “123456”); 123456\0放在常量區(qū),編譯器可能會將它與2所指向的"abcdefg"
優(yōu)化成一個(gè)地方。
}
棧和堆的區(qū)別
(1)申請后系統(tǒng)的響應(yīng)
棧:只要棧的剩余空間大于所申請空間,系統(tǒng)將為程序提供內(nèi)存,否則將報(bào)異常提示棧溢出。
堆:堆中空閑內(nèi)存地址是以鏈表方式進(jìn)行存儲的。當(dāng)需要申請分配時(shí),遍歷鏈表尋找第一個(gè)大于所申請空間的堆結(jié)點(diǎn),將此節(jié)點(diǎn)的空間分配給程序并且記錄本次分配的大小,以便于之后delete程序釋放內(nèi)存空間。
若找到的堆節(jié)點(diǎn)大于申請的大小,系統(tǒng)會將多余的部分重新放入空閑鏈表

(2)申請大小的限度
棧:在Windows下,棧是向低地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu), 是一塊連續(xù)的內(nèi)存的區(qū)域。棧頂?shù)牡刂泛蜅5淖畲笕萘渴窍到y(tǒng)預(yù)先規(guī)定好的,在 WINDOWS下,棧的大小是2M如果申請的空間超過棧的剩余空間時(shí),將提示overflow。因此,能從棧獲得的空間較小。
堆:堆是向高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),用鏈表來存儲,是不連續(xù)的內(nèi)存區(qū)域。而鏈表的遍歷方向是由低地址向高地址。堆的大小受限于計(jì)算機(jī)系統(tǒng)中有效的虛擬內(nèi)存。由此可見,堆獲得的空間比較靈活,也比較

(3)申請效率的比較:
棧:系統(tǒng)自動分配,速度較快。但程序員是無法控制的
堆:由new分配的內(nèi)存,一般速度比較慢,而且容易產(chǎn)生內(nèi)存碎片,不過用起來最方便.

(4)堆和棧中的存儲內(nèi)容
棧: 在函數(shù)調(diào)用時(shí),第一個(gè)進(jìn)棧的是主函數(shù)中后的下一條指令(函數(shù)調(diào)用語句的下一條可執(zhí)行語句)的地址,然后是函數(shù)的各個(gè)參數(shù),在大多數(shù)的C編譯器中,參數(shù)是由右往左入棧的,然后是函數(shù)中的局部變量。注意靜態(tài)變量是不入棧的,會進(jìn)入全局?jǐn)?shù)據(jù)區(qū)當(dāng)本次函數(shù)調(diào)用結(jié)束后,局部變量先出棧,然后是參數(shù),最后棧頂指針指向最開始存的地址,也就是主函數(shù)中的下一條指令,程序由該點(diǎn)繼續(xù)運(yùn)行
堆:一般是在堆的頭部用一個(gè)字節(jié)存放堆的大小。堆中的具體內(nèi)容有程序員安排。

參考資源:
https://www.jianshu.com/p/e01680c00de4
https://blog.csdn.net/zhanglei8893/article/details/6101076
https://blog.csdn.net/qq_36347375/article/details/91354349
https://www.cnblogs.com/LittleHann/p/3454748.html
https://www.cnblogs.com/itzxy/p/9293677.html

總結(jié)

以上是生活随笔為你收集整理的高级操作系统——XV6进程管理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。