国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

MIT6.S081學(xué)習(xí)筆記--lec 1

這篇具有很好參考價(jià)值的文章主要介紹了MIT6.S081學(xué)習(xí)筆記--lec 1。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

引言

操作系統(tǒng)的目標(biāo)

  • abstract H/W 抽象化硬件
  • multiplex 多路復(fù)用
  • isolation 隔離性
  • sharing 共享(進(jìn)程通信,數(shù)據(jù)共享)
  • security / access control 安全性/權(quán)限控制
  • performance 性能/內(nèi)核開銷
  • range of applications 多應(yīng)用場景

操作系統(tǒng)概覽

操作系統(tǒng)應(yīng)該提供的功能:1. 多進(jìn)程支持 2. 進(jìn)程間隔離 3. 受控制的進(jìn)程間通信

  • xv6:一種在本課程中使用的類UNIX的教學(xué)操作系統(tǒng),運(yùn)行在RISC-V指令集處理器上,本課程中將使用QEMU模擬器代替

  • kernel(內(nèi)核):為運(yùn)行的程序提供服務(wù)的一種特殊程序。每個(gè)運(yùn)行著的程序叫做進(jìn)程,每個(gè)進(jìn)程的內(nèi)存中存儲(chǔ)指令、數(shù)據(jù)和堆棧。一個(gè)計(jì)算機(jī)可以擁有多個(gè)進(jìn)程,但是只能有一個(gè)內(nèi)核

    每當(dāng)進(jìn)程需要調(diào)用內(nèi)核時(shí),它會(huì)觸發(fā)一個(gè)system call(系統(tǒng)調(diào)用),system call進(jìn)入內(nèi)核執(zhí)行相應(yīng)的服務(wù)然后返回。

操作系統(tǒng)的組織結(jié)構(gòu)如圖1所示

MIT6.S081學(xué)習(xí)筆記--lec 1

內(nèi)核提供的一系列系統(tǒng)調(diào)用就是用戶程序可見的操作系統(tǒng)接口,xv6 內(nèi)核提供了 Unix 傳統(tǒng)系統(tǒng)調(diào)用的一部分,它們是:

MIT6.S081學(xué)習(xí)筆記--lec 1

進(jìn)程和內(nèi)存

每個(gè)進(jìn)程擁有自己的用戶空間內(nèi)存以及內(nèi)核空間狀態(tài),當(dāng)進(jìn)程不再執(zhí)行時(shí)xv6將存儲(chǔ)和這些進(jìn)程相關(guān)的CPU寄存器直到下一次運(yùn)行這些進(jìn)程。kernel將每一個(gè)進(jìn)程用一個(gè)PID(process identifier)指代。在進(jìn)程執(zhí)行中,常常會(huì)使用forkexec系統(tǒng)調(diào)用來創(chuàng)建新的進(jìn)程。如下面代碼所示:

fork and wait

  • fork:形式:int fork()。其作用是讓一個(gè)進(jìn)程生成另外一個(gè)和這個(gè)進(jìn)程的內(nèi)存內(nèi)容相同的子進(jìn)程。在父進(jìn)程中,fork的返回值是這個(gè)子進(jìn)程的PID,在子進(jìn)程中,返回值是0
  • exit:形式:int exit(int status)。讓調(diào)用它的進(jìn)程停止執(zhí)行并且將內(nèi)存等占用的資源全部釋放。需要一個(gè)整數(shù)形式的狀態(tài)參數(shù),0代表以正常狀態(tài)退出,1代表以非正常狀態(tài)退出
  • wait:形式:int wait(int *status)。等待子進(jìn)程退出,返回子進(jìn)程PID,子進(jìn)程的退出狀態(tài)存儲(chǔ)到int *status這個(gè)地址中。如果調(diào)用者沒有子進(jìn)程,wait將返回-1
  • pipe:形式:int pipe(int p[])。創(chuàng)建一個(gè)管道,將讀/寫文件描述符放在p[0]和p[1]中
  • sbrk:形式:char *sbrk(int n)。將進(jìn)程的內(nèi)存增加n字節(jié)。返回新內(nèi)存的起始位置。
int pid = fork();
if (pid > 0) {
    printf("parent: child=%d\n", pid);
    pid = wait((int *) 0);
    printf("child %d is done\n", pid);
} else if (pid == 0) {
    printf("child: exiting\n");
    exit(0);
} else {
    printf("fork error\n");
}

前兩行輸出可能是

parent: child=1234
child: exiting

也可能是

child: exiting
parent: child=1234

這是因?yàn)樵趂ork了之后,父進(jìn)程和子進(jìn)程將同時(shí)開始判斷PID的值,在父進(jìn)程中,PID為1234,而在子進(jìn)程中,PID為0。看哪個(gè)進(jìn)程先判斷好PID的值,以上輸出順序才會(huì)被決定。

最后一行輸出為

parent: child 1234 is done

子進(jìn)程在判斷完pid == 0之后將exit,父進(jìn)程發(fā)現(xiàn)子進(jìn)程exit之后,wait執(zhí)行完畢,打印輸出。

盡管fork了之后子進(jìn)程和父進(jìn)程有相同的內(nèi)存內(nèi)容,但是內(nèi)存地址和寄存器是不一樣的,也就是說在一個(gè)進(jìn)程中改變變量并不會(huì)影響另一個(gè)進(jìn)程。

fork and exec

exec:形式:int exec(char *file, char *argv[])。加載一個(gè)文件,獲取執(zhí)行它的參數(shù),執(zhí)行。如果執(zhí)行錯(cuò)誤返回-1,執(zhí)行成功則不會(huì)返回,而是開始從文件入口位置開始執(zhí)行命令。文件必須是ELF格式。

xv6 shell使用以上四個(gè)system call來為用戶執(zhí)行程序。在shell進(jìn)程的main中主循環(huán)先通過getcmd來從用戶獲取命令,然后調(diào)用fork來運(yùn)行一個(gè)和當(dāng)前shell進(jìn)程完全相同的子進(jìn)程。父進(jìn)程調(diào)用wait等待子進(jìn)程exec執(zhí)行完(在runcmd中調(diào)用exec

/* sh.c */
int
main(void)
{
  static char buf[100];
  int fd;

  // Ensure that three file descriptors are open.
  while((fd = open("console", O_RDWR)) >= 0){
    if(fd >= 3){
      close(fd);
      break;
    }
  }

  // Read and run input commands.
  while(getcmd(buf, sizeof(buf)) >= 0){
    if(buf[0] == 'c' && buf[1] == 'd' && buf[2] == ' '){
      // Chdir must be called by the parent, not the child.
      buf[strlen(buf)-1] = 0;  // chop \n
      if(chdir(buf+3) < 0)
        fprintf(2, "cannot cd %s\n", buf+3);
      continue;
    }
    if(fork1() == 0)
      runcmd(parsecmd(buf));
    // parent wait the child exit
    wait(0);
  }
  exit(0);
}

你可能會(huì)想,既然forkexec總是一起使用,為什么不合并成一個(gè)呢?實(shí)際上我們可以在fork 之后,對子進(jìn)程進(jìn)行一些設(shè)置,比如輸入/輸出重定向,然后再執(zhí)行exec,注意exec并不會(huì)改變子進(jìn)程的file table。

當(dāng)我們不需要進(jìn)行額外的設(shè)置時(shí),fork 復(fù)制內(nèi)存,exec替換內(nèi)存,這意味著內(nèi)存的浪費(fèi),有什么辦法可以優(yōu)化這種情況么?答案是肯定的,之后的4.6節(jié)我們會(huì)講到 COW (copy-on-write)機(jī)制。

I/O 和文件描述符

  • file descriptor:文件描述符,用來表示一個(gè)被內(nèi)核管理的、可以被進(jìn)程讀/寫的對象的一個(gè)整數(shù),表現(xiàn)形式類似于字節(jié)流,通過打開文件、目錄、設(shè)備等方式獲得。一個(gè)文件被打開得越早,文件描述符就越小。

    每個(gè)進(jìn)程都擁有自己獨(dú)立的文件描述符列表,其中0是標(biāo)準(zhǔn)輸入,1是標(biāo)準(zhǔn)輸出,2是標(biāo)準(zhǔn)錯(cuò)誤。shell將保證總是有3個(gè)文件描述符是可用的

    while((fd = open("console", O_RDWR)) >= 0)
    {    
        if(fd >= 3)
        {        
            close(fd);        
            break;    
        } 
    }
    
  • readwrite:形式int write(int fd, char *buf, int n)int read(int fd, char *bf, int n)。從/向文件描述符fd讀/寫n字節(jié)bf的內(nèi)容,返回值是成功讀取/寫入的字節(jié)數(shù)。每個(gè)文件描述符有一個(gè)offset,read會(huì)從這個(gè)offset開始讀取內(nèi)容,讀完n個(gè)字節(jié)之后將這個(gè)offset后移n個(gè)字節(jié),下一個(gè)read將從新的offset開始讀取字節(jié)。write也有類似的offset

    /* essence of cat program */ 
    char buf[512]; 
    int n; 
    
    for (;;) 
    {    
        n = read(0, buf, sizeof buf);    
        if (n == 0)        
        break;    
        if (n < 0)
        {        
            fprintf(2, "read error\n");        
            exit(1);    
        }    
        if (write(1, buf, n) != n)
        {        
            fprintf(2, "write error\n");        
            exit(1);    
        } 
    }
    
  • close。形式是int close(int fd),將打開的文件fd釋放,使該文件描述符可以被后面的openpipe等其他system call使用。

    使用close來修改file descriptor table能夠?qū)崿F(xiàn)I/O重定向

    /* implementation of I/O redirection, * more specifically, cat < input.txt */ 
    char *argv[2]; 
    argv[0] = "cat"; 
    argv[1] = 0; 
    if (fork() == 0) {   // in the child process    
        close(0);  // this step is to release the stdin file descriptor    
        open("input.txt", O_RDONLY);  // the newly allocated fd for input.txt is 0, since the previous fd 0 is released    
        exec("cat", argv);  // execute the cat program, by default takes in the fd 0 as input, which is input.txt 
    }
    

    父進(jìn)程的fd table將不會(huì)被子進(jìn)程fd table的變化影響,但是文件中的offset將被共享。

  • dup。形式是int dup(int fd),復(fù)制一個(gè)新的fd指向的I/O對象,返回這個(gè)新fd值,兩個(gè)I/O對象(文件)的offset相同

    e.g.

    fd = dup(1);
    write(1, "hello ", 6); 
    write(fd, "world\n", 6); 
    // outputs hello world
    

    除了dupfork之外,其他方式不能使兩個(gè)I/O對象的offset相同,比如同時(shí)open相同的文件

Pipes

pipe:管道,暴露給進(jìn)程的一對文件描述符,一個(gè)文件描述符用來讀,另一個(gè)文件描述符用來寫,將數(shù)據(jù)從管道的一端寫入,將使其能夠被從管道的另一端讀出。

我們之前有提到過pipe是一個(gè)system call,形式為int pipe(int p[]),p[0]為讀取的文件描述符,p[1]為寫入的文件描述符。

xv6中有這樣一個(gè)例子,通過寫管道將參數(shù)傳遞給wc程序

/* run the program wc with stdin connected to the read end of pipe, parent process able to communicate with child process */
int p[2];
char *argv[2];

argv[0] = "wc";
argv[1] = 0;

pipe(p); // read fd put into p[0], write fd put into p[1]
if (fork() == 0) {
    close(0);
    dup(p[0]); // make the fd 0 refer to the read end of pipe
    close(p[0]); // original read end of pipe is closed
    close(p[1]); // fd p[1] is closed in child process, but not closed in the parent process. 注意這里關(guān)閉p[1]非常重要,因?yàn)槿绻魂P(guān)閉p[1],管道的讀取端會(huì)一直等待讀取,wc就永遠(yuǎn)也無法等到EOF
    exec("/bin/wc", argv); // by default wc will take fd 0 as the input, which is the read end of pipe in this case
} else {
    close(p[0]); // close the read end of pipe in parent process will not affect child process
    write(p[1], "hello world\n", 12); 
    close(p[1]); // write end of pipe closed, the pipe shuts down
}

在xv6的shell實(shí)現(xiàn)中即sh.c也是類似的實(shí)現(xiàn),關(guān)于pipe系統(tǒng)調(diào)用的源碼閱讀,我也總結(jié)了一份代碼講解。

case PIPE:
pcmd = (struct pipecmd*)cmd;
if(pipe(p) < 0)
    panic("pipe");
if(fork1() == 0){
    // in child process
    close(1); // close stdout
    dup(p[1]); // make the fd 1 as the write end of pipe
    close(p[0]);
    close(p[1]);
    runcmd(pcmd->left); // run command in the left side of pipe |, output redirected to the write end of pipe
}
if(fork1() == 0){
    // in child process
    close(0); // close stdin
    dup(p[0]); // make the fd 0 as the read end of pipe
    close(p[0]);
    close(p[1]);
    runcmd(pcmd->right); //  run command in the right side of pipe |, input redirected to the read end of pipe
}
close(p[0]);
close(p[1]);
wait(0); // wait for child process to finish
wait(0); // wait for child process to finish
break;

文件系統(tǒng)

xv6文件系統(tǒng)包含了文件(byte arrays)和目錄(對其他文件和目錄的引用)。目錄生成了一個(gè)樹,樹從根目錄/開始。對于不以/開頭的路徑,認(rèn)為是是相對路徑

  • mknod:創(chuàng)建設(shè)備文件,一個(gè)設(shè)備文件有一個(gè)major device #和一個(gè)minor device #用來唯一確定這個(gè)設(shè)備。當(dāng)一個(gè)進(jìn)程打開了這個(gè)設(shè)備文件時(shí),內(nèi)核會(huì)將readwrite的system call重新定向到設(shè)備上。
  • 一個(gè)文件的名稱和文件本身是不一樣的,文件本身,也叫inode,可以有多個(gè)名字,也叫link,每個(gè)link包括了一個(gè)文件名和一個(gè)對inode的引用。一個(gè)inode存儲(chǔ)了文件的元數(shù)據(jù),包括該文件的類型(file, directory or device)、大小、文件在硬盤中的存儲(chǔ)位置以及指向這個(gè)inode的link的個(gè)數(shù)
  • fstat。一個(gè)system call,形式為int fstat(int fd, struct stat *st),將inode中的相關(guān)信息存儲(chǔ)到st中。
  • link。一個(gè)system call,將創(chuàng)建一個(gè)指向同一個(gè)inode的文件名。unlink則是將一個(gè)文件名從文件系統(tǒng)中移除,只有當(dāng)指向這個(gè)inode的文件名的數(shù)量為0時(shí)這個(gè)inode以及其存儲(chǔ)的文件內(nèi)容才會(huì)被從硬盤上移除

注意:Unix提供了許多在用戶層面的程序來執(zhí)行文件系統(tǒng)相關(guān)的操作,比如mkdirln、rm等,而不是將其放在shell或kernel內(nèi),這樣可以使用戶比較方便地在這些程序上進(jìn)行擴(kuò)展。但是cd是一個(gè)例外,它是在shell程序內(nèi)構(gòu)建的,因?yàn)樗仨氁淖冞@個(gè)calling shell本身指向的路徑位置,如果是一個(gè)和shell平行的程序,那么它必須要調(diào)用一個(gè)子進(jìn)程,在子進(jìn)程里起一個(gè)新的shell,再進(jìn)行cd,這是不符合常理的。文章來源地址http://www.zghlxwxcb.cn/news/detail-576489.html

到了這里,關(guān)于MIT6.S081學(xué)習(xí)筆記--lec 1的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • MIT6.828/6.S081 Mac OS下搭建xv6和risc-v

    MIT6.828/6.S081 Mac OS下搭建xv6和risc-v

    題外話: 其實(shí)我是一名非計(jì)算機(jī)專業(yè)的在校生,因?yàn)閷浖_發(fā)和服務(wù)器開發(fā)很感興趣,并且這方面的就業(yè)相對我來說資源比較充沛,所以就學(xué)習(xí)了mit6.828的實(shí)驗(yàn) 課程的學(xué)習(xí)直接跟著官網(wǎng)的schedule走就行,先看Lecture下提供的講義和手冊,然后完成相應(yīng)的Lab,Lab共計(jì)10個(gè),主要

    2024年03月09日
    瀏覽(23)
  • MIT6.024學(xué)習(xí)筆記(三)——圖論(2)

    MIT6.024學(xué)習(xí)筆記(三)——圖論(2)

    科學(xué)是使人變得勇敢的最好途徑?!剪斨Z 在通信網(wǎng)絡(luò)中,分為主機(jī)和路由器兩部分,我們將主機(jī)分為輸入端和輸出端,則構(gòu)成的圖中有三部分:路由器、輸入端、輸出端,構(gòu)成了一個(gè)有向圖。那么,一個(gè)N*N規(guī)模的通信網(wǎng)絡(luò),應(yīng)該怎么構(gòu)成才能達(dá)到性能最佳呢(假設(shè)N總是

    2024年02月09日
    瀏覽(23)
  • MIT 6.S081學(xué)習(xí)筆記(第〇章)

    MIT 6.S081學(xué)習(xí)筆記(第〇章)

    本文涉及 xv6 《第零章 操作系統(tǒng)接口》相關(guān),主要對涉及的進(jìn)程、I/O、文件描述符、管道、文件等內(nèi)容產(chǎn)生個(gè)人理解,不具有官方權(quán)威解釋; 文章的目錄與書中的目錄沒有嚴(yán)格的相關(guān)性; 文中會(huì)有問題 (Question) 字段,這來源于對 xv6 book 的擴(kuò)展; 文中涉及的代碼均能在macOS

    2024年02月09日
    瀏覽(33)
  • mit6.828 - lab5筆記(上)

    unix的文件系統(tǒng)相關(guān)知識(shí) unix將可用的磁盤空間劃分為兩種主要類型的區(qū)域: inode區(qū)域 和 數(shù)據(jù)區(qū)域 。 unix為每個(gè)文件分配一個(gè)inode,其中保存文件的 關(guān)鍵元數(shù)據(jù) ,如文件的stat屬性和指向文件數(shù)據(jù)塊的指針。 數(shù)據(jù)區(qū)域中的空間會(huì)被分成大小相同的數(shù)據(jù)塊(就像內(nèi)存管理中的分

    2024年02月02日
    瀏覽(46)
  • MIT 6.S081 Lab Three

    MIT 6.S081 Lab Three

    本文為 MIT 6.S081 2020 操作系統(tǒng) 實(shí)驗(yàn)三解析。 MIT 6.S081課程前置基礎(chǔ)參考: 基于RISC-V搭建操作系統(tǒng)系列 在本實(shí)驗(yàn)中,您將探索頁表并對其進(jìn)行修改,以簡化將數(shù)據(jù)從用戶空間復(fù)制到內(nèi)核空間的函數(shù)。 開始編碼之前,請閱讀xv6手冊的第3章和相關(guān)文件: * kernel/memlayout.h* ,它捕獲了

    2024年02月09日
    瀏覽(20)
  • MIT6.5830 Lab1-GoDB實(shí)驗(yàn)記錄(五)

    完成了Exercise 1,還有四個(gè)Exercise在等著我,慢慢來吧。 實(shí)驗(yàn)準(zhǔn)備 了解緩沖池 緩沖池,俗稱BP。相關(guān)的概念還有數(shù)據(jù)頁和緩存頁。頁(Pages)的概念和操作系統(tǒng)中“分頁”的概念是一樣的,指的都是把邏輯地址空間分為若干同等大小的頁,并從0開始編號(hào)。 而緩沖池(Buffer Po

    2024年02月05日
    瀏覽(23)
  • MIT6.5830 Lab1-GoDB實(shí)驗(yàn)記錄(四)

    標(biāo)簽:Golang 讀寫緩沖區(qū)我是一點(diǎn)思路都沒有,所以得單獨(dú)開篇文章記錄。 實(shí)驗(yàn)補(bǔ)充 了解buffer、序列化與反序列化 這里的序列化,簡單來說類似于把一個(gè)很長的字符串拆成一個(gè)個(gè)字符;反序列化就是把這一個(gè)個(gè)字符拼回成完整的字符串。此處我們需要根據(jù)所給的Tuple,轉(zhuǎn)換為

    2024年02月06日
    瀏覽(19)
  • 【MIT 6.S081】Lab7: Multithreading

    本Lab比較簡單,就是為xv6添加一個(gè)用戶級(jí)的多線程功能,然后熟悉一下Linux下多線程編程。 筆者用時(shí)約2h 這一部分的代碼不涉及內(nèi)核代碼,所以也比較簡單,根據(jù)提示修改 user/uthread.c 中的代碼即可。仿照內(nèi)核中進(jìn)程轉(zhuǎn)換函數(shù) swtch 的實(shí)現(xiàn)即可。首先,添加一個(gè) context 上下文結(jié)

    2023年04月09日
    瀏覽(28)
  • (MIT6.045)自動(dòng)機(jī)、可計(jì)算性和復(fù)雜性-圖靈機(jī)

    (MIT6.045)自動(dòng)機(jī)、可計(jì)算性和復(fù)雜性-圖靈機(jī)

    有窮自動(dòng)機(jī)(FA)對有限存儲(chǔ)量設(shè)備是比較好的模型,下推自動(dòng)機(jī)對無限存儲(chǔ)設(shè)備是較好的模型(但是其存儲(chǔ)只能用后進(jìn)先出的棧模式來使用。)這兩個(gè)模型過于局限,不能作為通用模型。 和FA相似,但是圖靈機(jī)有無限的存儲(chǔ)。圖靈機(jī)可以作實(shí)際計(jì)算機(jī)做的所有事情。但是也有圖

    2024年02月08日
    瀏覽(28)
  • MIT 6s081 lab2:system calls

    作業(yè)地址:Lab: System calls (mit.edu) Add $U/_trace to UPROGS in Makefile add a prototype for the system call to user/user.h , a stub to user/usys.pl , and a syscall number to kernel/syscall.h . The Makefile invokes the perl script user/usys.pl Add a sys_trace() function in kernel/sysproc.c that implements the new system call by remembering its argument

    2024年01月18日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包