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

操作系統(tǒng)復(fù)習(xí) MITS6.1810 lab util 記錄

這篇具有很好參考價(jià)值的文章主要介紹了操作系統(tǒng)復(fù)習(xí) MITS6.1810 lab util 記錄。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

lab util

sleep

  1. 介紹:主要用來(lái)熟悉下環(huán)境以及代碼結(jié)構(gòu)。

    • See kernel/sysproc.c for the xv6 kernel code that implements the sleep system call (look for sys_sleep), user/user.h for the C definition of sleep callable from a user program, and user/usys.S for the assembler code that jumps from user code into the kernel for sleep.
  2. 代碼:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-615929.html

    #include "kernel/types.h"
    #include "user/user.h"
    
    int main(int argc, char *argv[])
    {
      if (argc <= 1) {
        fprintf(2, "usage: sleep `time`...\n");
      }
      
      int tick_num = atoi(argv[1]);
      sleep(tick_num);
      
      exit(0);
    }
    

pingpong

  1. 單個(gè)管道一般用于單向通信,父子進(jìn)程可通過(guò)兩個(gè)管道進(jìn)行雙向通信。(管道詳細(xì)行為參考 primes 實(shí)驗(yàn)部分)

  2. 代碼:

    #include "kernel/types.h"
    #include "user/user.h"
    
    #define BUFFSIZE 128
    
    void perror_exit(char* err_msg) {
      fprintf(2, "%s\n", err_msg);
      exit(-1);
    }
    
    int main(int argc, char *argv[])
    {
      int toson_fd[2];
      int toparent_fd[2];
    
      int ret1 = pipe(toson_fd);
      int ret2 = pipe(toparent_fd);
      if (ret1 == -1 || ret2 == -1) {
        perror_exit("pipe error");
      }
      
      int pid = fork();
      if (pid == -1) { // 
        perror_exit("fork error");
      } else if (pid == 0) { // child process
        close(toson_fd[1]);
        close(toparent_fd[0]);
    
        // read from the pipe1
        char buf[BUFFSIZE];
        int rbytes = read(toson_fd[0], buf, sizeof(buf));
        if (rbytes == -1) {
          perror_exit("read error");
        }
        buf[rbytes] = '\0';
        
        // print the msg from parent
        fprintf(1, "%d: received %s\n", getpid(), buf);
    
        // write response to parent (to pipe2)
        char resp[4] = "pong";
        int ret = write(toparent_fd[1], resp, sizeof(resp));
        if (ret == -1) {
          perror_exit("write error");
        }
      } else { // parent process
        close(toson_fd[0]);
        close(toparent_fd[1]);
    
        // write to son
        char msg[4] = "ping";
        int ret = write(toson_fd[1], msg, sizeof(msg));
        if (ret == -1) {
          perror_exit("write error");
        }
    
        // read from son
        char buf[BUFFSIZE];
        int rbytes = read(toparent_fd[0], buf, sizeof(buf));
        if (rbytes == -1) {
          perror_exit("read");
        }
        buf[rbytes] = '\0';
    
        // print the resp from son
        fprintf(1, "%d: received %s\n", getpid(), buf);
      }
    
      exit(0);
    }
    

primes

介紹

實(shí)驗(yàn)要求通過(guò) fork 和 pipe 系統(tǒng)調(diào)用建立起如下素?cái)?shù)篩的 pipeline.

p = get a number from left neighbor
print p
loop:
    n = get a number from left neighbor
    if (p does not divide n)
        send n to right neighbor

操作系統(tǒng)復(fù)習(xí) MITS6.1810 lab util 記錄

思路

CSP 的關(guān)鍵點(diǎn)在于:?jiǎn)蝹€(gè)步驟內(nèi)部操作是串行的,所有步驟之間是并發(fā)的。步驟之間的通信通過(guò)特定的 channel 完成,這里通過(guò) pipe 完成。

如上圖,除去第一個(gè)進(jìn)程和最后一個(gè)進(jìn)程,每個(gè)進(jìn)程有兩種身份(父/子)。

分析上述 pipeline, 每個(gè)進(jìn)程需做如下事情:

  1. 從 left-side-pipe 中讀取數(shù)據(jù),嘗試打印素?cái)?shù) prime。

    • 如果 left-side-pipe 的寫端關(guān)閉且沒(méi)讀到數(shù)據(jù),代表沒(méi)有數(shù)據(jù)到達(dá)。本進(jìn)程任務(wù)結(jié)束,正常 exit.
  2. 建立一個(gè)新的 right-side-pipe, fork 出一個(gè)子進(jìn)程, 自身即作為“父身份”根據(jù)第一步得出的 prime 進(jìn)行 filter, 將過(guò)濾后的數(shù)據(jù)傳入 right-side-pipe. wait 子進(jìn)程,等待子進(jìn)程打印結(jié)束。

    • 進(jìn)程 p0 由 shell fork 創(chuàng)建,如果 p0 不 wait 子進(jìn)程,父進(jìn)程 p0 可能在所有子進(jìn)程打印完成前結(jié)束,此時(shí) shell 會(huì)向終端輸出提示符$,造成 $ 穿插在打印結(jié)果中的現(xiàn)象。
    • 不 wait:
      • 子進(jìn)程還在運(yùn)行,父進(jìn)程結(jié)束 -> 孤兒進(jìn)程 -> 由 init 收養(yǎng)。缺點(diǎn):原父進(jìn)程得不到子進(jìn)程的狀態(tài)。
      • 父進(jìn)程還在運(yùn)行,子進(jìn)程結(jié)束 -> 僵尸進(jìn)程。缺點(diǎn):占用資源得不到釋放 (task_struct)。

notes: fork 出來(lái)的子進(jìn)程重復(fù)上述操作。

注意點(diǎn)

  • 注意 close(pipe) 的時(shí)機(jī),最保險(xiǎn)的做法是盡可能早關(guān)閉不需要的讀寫端。
  • wait 操作。
  • 錯(cuò)誤處理。

代碼

#include "kernel/types.h"
#include "user/user.h"

#define NULL 0

void perror_exit(char* err_msg) {
  fprintf(2, "%s\n", err_msg);
  exit(-1);
}

void child_processing(int left_pipe[2]) {
  // every process do things below:
  // 0. read from left-side pipe, and try to print a prime.
  // 1. create a new right-side pipe, do fork, pass the filtered data to right-side pipe.
  // notes: The new child processes forked will recursively do the above tasks.

  close(left_pipe[1]);
  int prime;
  int rbytes = read(left_pipe[0], &prime, sizeof(prime));
  if (rbytes == -1) {
    close(left_pipe[0]);
    perror_exit("read error");
  } else if (rbytes == 0) {
    // No more data reaches here
    close(left_pipe[0]);
    exit(0);
  } else {
    fprintf(1, "prime %d\n", prime);
  }

  int right_pipe[2];
  int ret = pipe(right_pipe);
  if (ret == -1) {
    perror_exit("pipe error");
  }

  ret = fork();
  if (ret == -1) {
    perror_exit("fork error");
  } else if (ret > 0) { // parent/current process
    close(right_pipe[0]);

    // do filtering, write data into the right-side pipe
    int num;
    while ((rbytes = read(left_pipe[0], &num, sizeof(num))) != 0) {
      if (rbytes == -1) {
        perror_exit("read error");
      }
      if (num % prime != 0) {
        write(right_pipe[1], &num, sizeof(num));
      }
    }
    // if rbytes == 0, no more data reaches. the job of this process is done
    close(left_pipe[0]);
    close(right_pipe[1]);
    
    wait(NULL);
    exit(0);
  } else if (ret == 0) { // child process
    child_processing(right_pipe);
  }
} 

int main(int argc, char* argv[])
{
  int pipe_fds[2];
  int ret = pipe(pipe_fds);
  if (ret == -1) {
    perror_exit("pipe error");
  }

  // create child process
  int pid = fork();
  if (pid == -1) {
    perror_exit("fork error");
  } else if (pid == 0) {  // child process
    // read from pipe, do filtering and pass the data to next stage
    child_processing(pipe_fds);
  } else {  // parent process
    close(pipe_fds[0]);
    
    const int MAX = 35;
    for (uint32 i = 2; i <= MAX; ++ i) {
      write(pipe_fds[1], &i, sizeof(i));
    }
    close(pipe_fds[1]);

    wait(NULL);
  }

  exit(0);
}

知識(shí)點(diǎn)

  1. 多個(gè)寫者向同一管道寫數(shù)據(jù)時(shí),可以確保寫入不超過(guò) PIPE_BUF 字節(jié)的操作是原子的。
    • 即假設(shè) A 寫入數(shù)據(jù) aa; B 寫入數(shù)據(jù) bb. 可以保證管道內(nèi)數(shù)據(jù)必是 aabb 或者 bbaa,不會(huì)出現(xiàn) abab 此類交叉的情況。
    • 如果寫入數(shù)據(jù)量超過(guò)限制,內(nèi)核會(huì)將其切分成若干個(gè)片段進(jìn)行傳輸,write() 調(diào)用會(huì)阻塞直到所有數(shù)據(jù)都被寫入管道位置(此時(shí)便可能出現(xiàn)數(shù)據(jù)交叉的情況)。
  2. 如果管道的寫端被關(guān)閉,從讀端讀數(shù)據(jù)的進(jìn)程讀完所有剩余數(shù)據(jù)后,將會(huì)看到文件結(jié)束,read() 返回 0.
  3. 管道容量是有限的,非特權(quán)進(jìn)程可以通過(guò) fctnl(fd, F_SETPIPE_SIZE, size) 進(jìn)行修改,修改范圍為 pagesize 和 /proc/sys/fs/pipe-max-size 之間。
    • 更大的管道容量意味著更少的上下文切換。
  4. 管道用于單向通信,即某進(jìn)程在一端讀,另一進(jìn)程在一端寫。
    • 如果允許父子進(jìn)程都能夠讀/寫同一管道,那么會(huì)發(fā)生競(jìng)爭(zhēng),需要額外的同步機(jī)制。
    • 如果需要雙向通信,分別在兩個(gè)方向上各設(shè)立一個(gè)管道即可。
  5. 關(guān)閉未使用管道 fd.
    • 如果讀進(jìn)程沒(méi)有關(guān)閉管道的寫端,那么在其他進(jìn)程關(guān)閉了寫入文件描述符后,讀者也不會(huì)看到文件結(jié)束,因?yàn)閮?nèi)核知道至少還存在一個(gè)管道的寫入描述符打開(kāi)著,即讀取進(jìn)程自己。
    • 如果寫進(jìn)程沒(méi)有關(guān)閉管道的讀端,那么即使其他進(jìn)程已經(jīng)關(guān)閉了讀端文件描述符,寫進(jìn)程仍然能夠向管道中寫入數(shù)據(jù),最后管道被寫滿,后續(xù)的寫入請(qǐng)求會(huì)被永遠(yuǎn)阻塞。
  6. 當(dāng)進(jìn)程嘗試向一個(gè)管道寫入數(shù)據(jù),但是沒(méi)有進(jìn)程占用該管道讀端時(shí),內(nèi)核會(huì)向進(jìn)程發(fā)送 SIGPIPE 信號(hào),默認(rèn)處理會(huì)殺死進(jìn)程。

find

  1. 思路:查找待查找目錄下所有條目:

    • 如果是目錄,遞歸查找
    • 如果是普通文件,比對(duì)文件名,輸出
  2. 實(shí)現(xiàn):參考 ls.c 實(shí)現(xiàn)。目錄文件本質(zhì)也是一個(gè)文件,不過(guò)文件內(nèi)容是一個(gè)個(gè) directory entry. 因此對(duì)于目錄,讀取其文件內(nèi)容至 dir_entry 中,判斷其類型,進(jìn)行相應(yīng)處理。

  3. 代碼:

#include "kernel/types.h"
#include "kernel/stat.h"
#include "kernel/fs.h"
#include "user/user.h"

char* fmtname(char *path) {
  static char buf[DIRSIZ+1];
  char *p;

  // Find first character after last slash.
  for (p = path + strlen(path); p >= path && *p != '/'; p--)
    ;
  p++;

  // Return blank-padded name.
  if (strlen(p) >= DIRSIZ)
    return p;
  memmove(buf, p, strlen(p));
  memset(buf+strlen(p), ' ', DIRSIZ-strlen(p));
  return buf;
}


void find(char* path, char* file_name) {
  int fd = open(path, 0);
  if (fd < 0) {
    fprintf(2, "find: cannot open %s\n", path);
    goto clean;
  }

  int ret;
  struct stat st;
  ret = fstat(fd, &st);
  if (ret < 0) {
    fprintf(2, "find: cannot stat %s\n", path);
    goto clean;
  }

  if (st.type != T_DIR) {
    fprintf(2, "find: the first param should be directory\n");
    goto clean;
  }

  char buf[512];
  if (strlen(path) + 1 + DIRSIZ + 1 > sizeof buf) {
    fprintf(2, "find: path too long\n");
    goto clean;
  }

  
  strcpy(buf, path);
  char* p = buf + strlen(buf);
  *p++ = '/';
  struct dirent de;
  while (read(fd, &de, sizeof(de)) == sizeof(de)){
    if (de.inum == 0)
      continue;
    memmove(p, de.name, DIRSIZ);
    p[DIRSIZ] = '\0';
    
    if (stat(buf, &st) < 0) {
      printf("find: cannot stat %s\n", buf);
      continue;
    }
    
    switch (st.type) {
      case T_FILE:  
        if (strcmp(file_name, de.name) == 0) {
          fprintf(1, "%s\n", buf);
        }
        break;
      case T_DIR:
        if (strcmp(".", de.name) != 0 && strcmp("..", de.name) != 0) {
          find(buf, file_name);
        }
        break;
      case T_DEVICE:
        break;
    }
  }

clean:
  close(fd);
  return;
}

int main(int argc, char *argv[])
{
  if (argc != 3) {
    fprintf(2, "Usage: %s <directory> <filename>\n", argv[0]);
    exit(1);
  }
  find(argv[1], argv[2]);
  
  exit(0);
}

到了這里,關(guān)于操作系統(tǒng)復(fù)習(xí) MITS6.1810 lab util 記錄的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • 操作系統(tǒng)期末復(fù)習(xí)題

    一、簡(jiǎn)答 1. 什么是進(jìn)程?它與程序相比有哪些特性? 進(jìn)程是進(jìn)程實(shí)體的運(yùn)行過(guò)程,是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位。 動(dòng)態(tài)性、獨(dú)立性、并發(fā)性 2. 什么是進(jìn)程?進(jìn)程靜態(tài)實(shí)體的組成是什么? 程序、數(shù)據(jù)集合、進(jìn)程控制塊PCB 3. 進(jìn)程的三種基本狀態(tài)是什么?畫出進(jìn)程的三

    2024年02月11日
    瀏覽(79)
  • 操作系統(tǒng)期末總復(fù)習(xí)結(jié)構(gòu)

    目錄 前言 操作系統(tǒng)引論 操作系統(tǒng)的目標(biāo) 操作系統(tǒng)的基本特征 操作系統(tǒng)的主要功能 系統(tǒng)調(diào)用的基本概念 進(jìn)程的描述與控制 進(jìn)程和程序的區(qū)別 程序?yàn)槭裁床荒懿l(fā)執(zhí)行(引入進(jìn)程的原因) 進(jìn)程的基本狀態(tài)與轉(zhuǎn)換 進(jìn)程通信的類型 線程的概念以及與進(jìn)程的區(qū)別及引入線程的原

    2024年02月15日
    瀏覽(19)
  • 北郵 操作系統(tǒng)期末復(fù)習(xí)(上)

    北郵 操作系統(tǒng)期末復(fù)習(xí)(上)

    這部分主要是針對(duì)北郵徐夢(mèng)瑋老師的操作系統(tǒng)課程做的考點(diǎn)總結(jié),基本上期末考試的內(nèi)容都是課堂上講解過(guò)的以及平時(shí)作業(yè)中出現(xiàn)過(guò)的知識(shí)點(diǎn)。 注意復(fù)習(xí)這門課程不要去找網(wǎng)上的題刷,網(wǎng)上的題和實(shí)際徐老師的期末考題差異會(huì)非常大。 操作系統(tǒng)的作用: 操作系統(tǒng)是硬件和用

    2024年02月03日
    瀏覽(27)
  • Linux網(wǎng)絡(luò)操作系統(tǒng)期末系統(tǒng)復(fù)習(xí)題

    一 、填空題 1. GUN 的含義是 一個(gè)自由的操作系統(tǒng) 。 2. Linux 一般有 3 個(gè)主要部分: 內(nèi)核 、 命令解釋層 、 實(shí)用工具 ?。 3. 目前被稱為純種的UNIX指的就是 System V 以及 BSD 這兩套操作系統(tǒng) 。 4. Linux是基于 Copyleft 的軟件模式進(jìn)行發(fā)布的,它是GNU項(xiàng)目制定的通用公共許可證,英文

    2023年04月23日
    瀏覽(29)
  • 操作系統(tǒng)期末復(fù)習(xí)應(yīng)用題

    操作系統(tǒng)期末復(fù)習(xí)應(yīng)用題

    1、假設(shè)計(jì)算機(jī)系統(tǒng)采用CSCAN(循環(huán)掃描)磁盤調(diào)度策略,使用2KB的內(nèi)存空間記錄16384個(gè)磁盤塊的空閑狀態(tài)。 (1)請(qǐng)說(shuō)明在上述條件下如何進(jìn)行磁盤塊空閑狀態(tài)管理 (2)設(shè)某單面磁盤旋轉(zhuǎn)速度為每分鐘6000轉(zhuǎn),每個(gè)磁道有100個(gè)扇區(qū),相鄰磁道間的平均移動(dòng)時(shí)間為1ms。若某時(shí)刻,

    2024年02月11日
    瀏覽(21)
  • 操作系統(tǒng)期末復(fù)習(xí)簡(jiǎn)記(更新中~)

    操作系統(tǒng)期末復(fù)習(xí)簡(jiǎn)記(更新中~)

    目錄 文件 文件的邏輯結(jié)構(gòu) 文件的目錄結(jié)構(gòu)? 文件系統(tǒng)的層次結(jié)構(gòu) 目錄實(shí)現(xiàn) 文件的分配(在磁盤上) 文件空閑空間管理 文件共享 1、繞彎路文件共享方 ?2、索引節(jié)點(diǎn)共享 ?3、符號(hào)鏈 I/O設(shè)備 基本概念 I/O設(shè)備分類 IO設(shè)備的構(gòu)成 IO控制器主要作用 IO控制器的組成 對(duì)IO設(shè)備的控

    2024年02月09日
    瀏覽(21)
  • 西電軟工操作系統(tǒng)復(fù)習(xí)綱要

    西電軟工操作系統(tǒng)復(fù)習(xí)綱要

    時(shí)間過(guò)得真快,轉(zhuǎn)眼大二已經(jīng)結(jié)束了。這學(xué)期軟工的課程雖然不多,但是感覺(jué)都挺抽象的,個(gè)人也是在復(fù)習(xí)上下了比較大的功夫(主要是平時(shí)也沒(méi)學(xué)),但最后的結(jié)果怎么說(shuō)的,不咋地… 以下內(nèi)容是個(gè)人根據(jù)復(fù)習(xí)提綱以及往年題進(jìn)行的知識(shí)點(diǎn)總結(jié),其中也會(huì)包含今年試題的回

    2024年02月08日
    瀏覽(55)
  • 計(jì)算機(jī)操作系統(tǒng)原理期末總復(fù)習(xí)

    計(jì)算機(jī)操作系統(tǒng)原理期末總復(fù)習(xí)

    1、現(xiàn)代操作系統(tǒng)的四個(gè)特征是什么?(4分) 并發(fā)、共享、虛擬、異步 并發(fā) :兩個(gè)或多個(gè)事件在 同一時(shí)間間隔內(nèi) 發(fā)生。 共享 :內(nèi)存中多個(gè)并發(fā)執(zhí)行的進(jìn)程共同使用系統(tǒng)中的資源。 2、操作系統(tǒng)內(nèi)核的四個(gè)主要功能是什么?(4分) 內(nèi)存管理、進(jìn)程管理、設(shè)備管理、文件管理

    2024年02月10日
    瀏覽(94)
  • 【第七章 | 輸入輸出系統(tǒng)】《操作系統(tǒng) 慕課版》課后答案 + 復(fù)習(xí)

    【第七章 | 輸入輸出系統(tǒng)】《操作系統(tǒng) 慕課版》課后答案 + 復(fù)習(xí)

    1.I/O系統(tǒng)的功能、模型和接口 I/O系統(tǒng) 管理的主要對(duì)象 : I/O設(shè)備 和對(duì)應(yīng)的 設(shè)備控制器 I/O系統(tǒng)的主要任務(wù): 完成用戶提出的I/O請(qǐng)求、提高I/O速率、改善I/O設(shè)備的利用率 I/O系統(tǒng)的基本功能: 夠隱藏物理設(shè)備的細(xì)節(jié)、保證OS與設(shè)備無(wú)關(guān)、提高處理機(jī)和I/O設(shè)備的利用率、對(duì)I/O設(shè)備

    2024年02月08日
    瀏覽(20)
  • 操作系統(tǒng)實(shí)驗(yàn) 2.3系統(tǒng)調(diào)用:linux-0.11-lab “為版本0內(nèi)核增加一個(gè)系統(tǒng)調(diào)用getjiffies” 和 “在用戶程序中使用新增的系統(tǒng)調(diào)用”

    操作系統(tǒng)實(shí)驗(yàn) 2.3系統(tǒng)調(diào)用:linux-0.11-lab “為版本0內(nèi)核增加一個(gè)系統(tǒng)調(diào)用getjiffies” 和 “在用戶程序中使用新增的系統(tǒng)調(diào)用”

    打開(kāi) vscode ,在如圖所示位置打開(kāi) ~/os/linux-0.11-lab/0 文件夾 1.定義getjiffies系統(tǒng)調(diào)用 題目中給的提示:進(jìn)入到 unistd.h 文件中 閱讀代碼,可以發(fā)現(xiàn)上圖劃線處有個(gè)系統(tǒng)調(diào)用名為 getpid :返回當(dāng)前進(jìn)程號(hào)——這與我們期望實(shí)現(xiàn)的功能類似:通過(guò)系統(tǒng)調(diào)用返回jiffies值。 于是此時(shí)希望

    2023年04月08日
    瀏覽(109)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包