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

歡迎訪問 生活随笔!

生活随笔

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

windows

操作系统实践(四/五)

發(fā)布時(shí)間:2025/3/15 windows 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 操作系统实践(四/五) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

??本次實(shí)驗(yàn)課的內(nèi)容涉及到以下幾個(gè)方面:
????1.文件的內(nèi)核實(shí)現(xiàn)
????2.標(biāo)準(zhǔn)的輸入輸出
????3.系統(tǒng)調(diào)用dup和pipe

??文件最基本的系統(tǒng)調(diào)用是open和close,open一個(gè)文件后會(huì)返回一個(gè)fd,作為這個(gè)文件的標(biāo)識(shí),后續(xù)有關(guān)于這個(gè)文件的操作都使用fd去完成。

1.文件的內(nèi)核實(shí)現(xiàn)

??文件的內(nèi)核實(shí)現(xiàn)中圍繞著四個(gè)結(jié)構(gòu)體:索引節(jié)點(diǎn)、file結(jié)構(gòu)體、文件描述符表、進(jìn)程控制塊。下面介紹下它們各自存儲(chǔ)的內(nèi)容:
??索引節(jié)點(diǎn)中保存了文件的大小、文件存放在磁盤的位置、文件的創(chuàng)建時(shí)間、修改時(shí)間、文件的所有者、文件的訪問權(quán)限
??file結(jié)構(gòu)體file結(jié)構(gòu)體存了被打開文件的信息、文件對(duì)應(yīng)的索引節(jié)點(diǎn)(inode)、文件的當(dāng)前訪問位置、文件的打開模式(只讀、只寫、可讀可寫)
??文件描述符表是一個(gè)數(shù)組,數(shù)組的元素類型是指針,指針指向一個(gè)file結(jié)構(gòu)體,用于保存被打開的文件。當(dāng)內(nèi)核打開文件時(shí),分配一個(gè)file結(jié)構(gòu)體表示被打開的文件,將該file結(jié)構(gòu)體指針保存在文件描述符表中
??進(jìn)程控制塊是操作系統(tǒng)表示進(jìn)程狀態(tài)的數(shù)據(jù)結(jié)構(gòu),存放用于描述進(jìn)程情況及控制進(jìn)程運(yùn)行所需的全部信息(進(jìn)程標(biāo)識(shí)信息、處理機(jī)狀態(tài)、進(jìn)程調(diào)度信息、打開文件列表,即文件描述符表,記錄了該進(jìn)程打開的文件)

2.標(biāo)準(zhǔn)的輸入輸出

??標(biāo)準(zhǔn)的輸入輸出就是指write和read

write(1, buf, sizeof(buf)); // 標(biāo)準(zhǔn)輸入,就是鍵盤輸入 read(0, buf, sizeof(buf)); //標(biāo)準(zhǔn)輸出,就是終端輸出

3.系統(tǒng)調(diào)用dup和pipe

?? dup(重定向)
??dup就是讓一個(gè)新的fd去指向一個(gè)文件,這樣文件就有了兩個(gè)指向。可以把老fd解放出來,去完成其他操作。
還有一個(gè)變形的dup2,完成一樣的功能。調(diào)用方式不同

??pipe(管道)
??pipe的實(shí)現(xiàn)是基于隊(duì)列,一端作為輸入端,一端作為輸出端。整體結(jié)構(gòu)如下:

??以上就是這次實(shí)驗(yàn)課的全部理論學(xué)習(xí)啦,下面看看作業(yè)吧!這次的作業(yè)沒有關(guān)于dup和pipe的內(nèi)容,是上節(jié)課mysys實(shí)現(xiàn)的變形。
??源代碼如下:

#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<sys/types.h> #include<sys/wait.h> #include<string.h>void mysys(char *command) {char *argv[512]; // 這里必須要用動(dòng)態(tài)指針數(shù)組,因?yàn)閑xecvp最后有一個(gè)NULL作為結(jié)束標(biāo)志,靜態(tài)的二維數(shù)組是無法實(shí)現(xiàn)的。int num = 0;char temp[512];for (int i=0; command[i]!='\0'; i++) {int index = 0;while (command[i]!='\0' && command[i] != ' ') {temp[index++] = command[i++];}temp[index] = '\0';if (command[i] == '\0')break;argv[num] = (char *)malloc(strlen(temp));strcpy(argv[num], temp);num++;}argv[num] = (char *)malloc(strlen(temp));strcpy(argv[num], temp);num++;argv[num] = NULL;pid_t pid;if (command == NULL)return ;if ((pid = fork()) < 0) {}else if (pid == 0) {execvp(argv[0], argv);exit(127);}else {sleep(1);}return ; }int main() {while (1) {write(1, "> ", 3); // 此處可以使用write/* printf("> "); 如果這樣使用printf是不可以的,printf有輸出緩沖區(qū),遇到\n才會(huì)統(tǒng)一調(diào)用一次write。實(shí)現(xiàn)的方式有兩種:1.printf("\n")2.fflush(stdout);*/// 在底層編程時(shí),使用printf就可以,更方便char buf[80];int count;count = read(0, buf, sizeof(buf));// buf[count] = 0; //這個(gè)是錯(cuò)的,輸入回車后,末尾還會(huì)讀入一個(gè)\nbuf[count-1] = 0;if (strcmp(buf, "exit") == 0)//exit(127)也可以;break;mysys(buf);}return 0; }

??第四次,打板兒!


??第五次的內(nèi)容和上次一樣的,區(qū)別的是作業(yè),就寫在一篇里了。
??源代碼如下:

#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<sys/types.h> #include<sys/wait.h> #include<string.h> #include<sys/stat.h> #include<fcntl.h>void mysys(char *command) {char *argv[512]; // 這里必須要用動(dòng)態(tài)指針數(shù)組,因?yàn)閑xecvp最后有一個(gè)NULL作為結(jié)束標(biāo)志,靜態(tài)的二維數(shù)組是無法實(shí)現(xiàn)的。int num = 0;char temp[512];for (int i=0; command[i]!='\0'; i++) {int index = 0;while (command[i]!='\0' && command[i] != ' ') {temp[index++] = command[i++];}temp[index] = '\0';if (command[i] == '\0')break;argv[num] = (char *)malloc(strlen(temp));strcpy(argv[num], temp);num++;}argv[num] = (char *)malloc(strlen(temp));strcpy(argv[num], temp);num++;argv[num] = NULL;pid_t pid;if (command == NULL)return ;if ((pid = fork()) < 0) {}else if (pid == 0) {/*思路:對(duì)輸入命令進(jìn)行判斷,如果是echo再進(jìn)一步判斷有沒有重定向標(biāo)志: >目標(biāo)文件,如果有按重定向方法寫入指定文件,否則按正常echo輸出`*/if (strcmp(argv[0], "echo") == 0) {int i, j;int tag = 0;for (i=0; i<num; i++) {for (j=0; argv[i][j] != '\0'; j++) {if (argv[i][j] = '>' && argv[i][j+1] != '\0' && i == num-1) {tag = 1;break;}}if (tag == 1)break;}if (tag == 1) { // tag為1說明存在重定向,下面截取目標(biāo)文件名及寫入內(nèi)容// 截取文件名char filename[10];int filename_index = 0;for (int j=1; argv[i][j]!='\0'; j++) {filename[filename_index++] = argv[i][j];}filename[filename_index] = '\0';char content[20];int content_index = 0;// 截取內(nèi)容,已知為echo命令,從5號(hào)以后為內(nèi)容for (int k=5; command[k]!='\0'; k++) {if (command[k] == '>') {content[content_index] = '\0';break;}else content[content_index++] = command[k];}// 使用重定向方式,將fd改為1int fd;fd = open(filename, O_CREAT|O_RDWR, 0777);dup2(fd, 1); // 函數(shù)格式(源,目標(biāo))write(1, content, sizeof(content));}else {execvp(argv[0], argv);}}elseexecvp(argv[0], argv); exit(127);}else {sleep(1);}return ; }int main() {while (1) {write(1, "> ", 3); // 此處需要使用write,用printf的話會(huì)不輸出char buf[80];int count;count = read(0, buf, sizeof(buf));// buf[count] = 0; //這個(gè)是錯(cuò)的,輸入回車后,末尾還會(huì)讀入一個(gè)\nbuf[count-1] = 0;if (strcmp(buf, "exit") == 0)break;mysys(buf);}return 0; }

??這次的作業(yè)主要是增加一個(gè)要求:echo另外一個(gè)內(nèi)容寫入指定文件(之前的echo是輸出到屏幕,重定向后將1號(hào)指向文件,就不會(huì)在上輸出了)。但悲催的是:我這份代碼能夠完成新功能,對(duì)于普通功能的echo沒用了(嗚嗚嗚),也就是echo a b c沒了反應(yīng),到現(xiàn)在也沒找到問題。如果有人看出來,請?jiān)谙路皆u(píng)論區(qū)留言,感謝!

??上節(jié)課老師還讓實(shí)現(xiàn)pwd,cd,使用execvp無法完成,想了好久都沒有結(jié)果,但其實(shí)是有系統(tǒng)調(diào)用的:

char *cwd = getcwd(buff,sizeof(buff)); // pwd,返回值cwd即為結(jié)果 chdir(comnd[1]); // cd,comnd為路徑

因作者水平有限,如有錯(cuò)誤之處,請?jiān)谙路皆u(píng)論區(qū)指正,謝謝!

新人創(chuàng)作打卡挑戰(zhàn)賽發(fā)博客就能抽獎(jiǎng)!定制產(chǎn)品紅包拿不停!

總結(jié)

以上是生活随笔為你收集整理的操作系统实践(四/五)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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