From da58ebc980afb42908fe41f5517f232fe752188e Mon Sep 17 00:00:00 2001 From: jls <2605141046@qq.com> Date: Sun, 22 Dec 2024 16:00:20 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E8=B5=9B=E6=96=87=E6=A1=A3=E6=8F=90?= =?UTF-8?q?=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...35\350\265\233\346\226\207\346\241\243.md" | 42 +++++++++++++++---- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git "a/doc/2024_\345\210\235\350\265\233\346\226\207\346\241\243.md" "b/doc/2024_\345\210\235\350\265\233\346\226\207\346\241\243.md" index 3110c39..0dc1026 100644 --- "a/doc/2024_\345\210\235\350\265\233\346\226\207\346\241\243.md" +++ "b/doc/2024_\345\210\235\350\265\233\346\226\207\346\241\243.md" @@ -2,12 +2,12 @@ - [åˆèµ›æ–‡æ¡£](#åˆèµ›æ–‡æ¡£) - [1.概述](#1概述) - - [2. 设计与实现]() + - [2. 设计与实现](#2-设计与实现) - [3. 总结与展望](#3-总结与展望) ## 1.概述 -我们ä¿ç•™äº†åŽŸ `xv6-k210` ä¸çš„æ‰€æœ‰æ–‡æ¡£ï¼Œæ–°æ–‡æ¡£ä¸æ·»åŠ äº†oså‰ç¼€çš„æ˜¯åˆå·¥å¤§å¦é•¿çš„一些工作,仓库为https://gitlab.eduxiji.net/educg-group-14238-914330/853476998-2958.gitï¼Œç”±äºŽæˆ‘ä»¬é˜Ÿä¼æ•´ä½“æ“作系统项目开å‘ç»éªŒå分ä¸è¶³ï¼Œå› æ¤æ‰“算在å‰è¾ˆçš„基础上进行一些æ“ä½œç³»ç»Ÿå†…æ ¸ä»£ç 编写的å¦ä¹ ï¼Œå…¶ä¸æ–‡æ¡£éƒ¨åˆ†å°†ä»¥2024为å‰ç¼€è¿›è¡ŒåŒºåˆ†ï¼Œå¯¹äºŽæ–‡æ¡£æè¿°ä¸å†²çªçš„部分,以新文档为准。 +我们ä¿ç•™äº†åŽŸ xv6-k210 ä¸çš„æ‰€æœ‰æ–‡æ¡£ï¼Œç”±äºŽæˆ‘ä»¬é˜Ÿä¼æ•´ä½“æ“作系统项目开å‘ç»éªŒå分ä¸è¶³ï¼Œå› æ¤æ‰“算在å‰è¾ˆçš„基础上进行一些æ“ä½œç³»ç»Ÿå†…æ ¸ä»£ç 编写的å¦ä¹ ï¼Œå…¶ä¸æ–‡æ¡£éƒ¨åˆ†å°†ä»¥2024为å‰ç¼€è¿›è¡ŒåŒºåˆ†ï¼Œå¯¹äºŽæ–‡æ¡£æè¿°ä¸å†²çªçš„部分,以新文档为准。 队员全部æ¥è‡ªåˆè‚¥å·¥ä¸šå¤§å¦ï¼Œç»„员以åŠåˆ†å·¥å¦‚下: @@ -71,7 +71,7 @@ void yield(void); void scheduler(void); ``` -在trap.cä¸è¦ç¡®ä¿æ—¶é’Ÿä¸æ–和时间片触å‘调度,主è¦åœ¨usertrap函数ä¸åœ¨which_dev==2çš„æ¡ä»¶ä¸ä¿®æ”¹ä¸ºï¼š +在trap.cä¸è¦ç¡®ä¿æ—¶é’Ÿä¸æ–和时间片触å‘调度,主è¦åœ¨usertrap函数ä¸åœ¨which_dev==2(ä»£è¡¨æ˜¯å®šæ—¶å™¨ä¸æ–)çš„æ¡ä»¶ä¸ä¿®æ”¹ä¸ºï¼š ```c if(which_dev == 2){ if(p && p->state == RUNNING) { // 检查当å‰è¿è¡Œçš„进程是å¦å˜åœ¨å¹¶åœ¨è¿è¡Œ @@ -149,7 +149,7 @@ scheduler(void) sfence_vma(); // 清除 TLB,确ä¿é¡µè¡¨åˆ‡æ¢åŽå†…å˜è®¿é—®æ£ç¡® // 切æ¢åˆ°é€‰ä¸çš„进程,ä¿å˜å½“å‰ CPU 的上下文到 c->context, - // 并切æ¢åˆ° p->context(用户进程的上下文) + // 并切æ¢åˆ° p->context(用户进程的上下文) å› æ¤ä¸åœ¨å®žé™…需è¦è°ƒç”¨sched函数 swtch(&c->context, &p->context); // 从用户进程返回åŽï¼Œåˆ‡æ¢å›žå†…æ ¸é¡µè¡¨ @@ -164,7 +164,7 @@ scheduler(void) p->queue_level++; // 将进程é™çº§åˆ°ä¸‹ä¸€ä¼˜å…ˆçº§é˜Ÿåˆ— } // 从当å‰é˜Ÿåˆ—ç§»å‡ºï¼Œå°†è¿›ç¨‹åŠ å…¥åˆ°å¯¹åº”çš„ä½Žä¼˜å…ˆçº§é˜Ÿåˆ— - mlfq[q][head] = 0; // 当å‰é˜Ÿåˆ—ä½ç½®ç½®ç©º + mlfq[q][head] = NULL; // 当å‰é˜Ÿåˆ—ä½ç½®ç½®ç©º mlfq[p->queue_level][queue_tail[p->queue_level]] = p; // åŠ å…¥æ–°é˜Ÿåˆ— queue_tail[p->queue_level] = (queue_tail[p->queue_level] + 1) % NPROC; // 更新新队列尾指针 } @@ -182,8 +182,9 @@ scheduler(void) } } - -修改yield函数 其作用是当当å‰è¿è¡Œçš„进程时间片用完,或者æŸä¸ªè¿›ç¨‹ä¸»åŠ¨è®©å‡º CPU 时,它会将当å‰è¿›ç¨‹ç½®ä¸º RUNNABLE 状æ€ï¼Œå¹¶è§¦å‘调度器æ¥é€‰æ‹©ä¸‹ä¸€ä¸ªåˆé€‚的进程è¿è¡Œã€‚在多级å馈队列(MLFQ)调度ä¸ï¼Œyield 需è¦è€ƒè™‘è¿›ç¨‹æ‰€åœ¨çš„é˜Ÿåˆ—çº§åˆ«ï¼Œè¿›ç¨‹çš„æ—¶é—´ç‰‡ä»¥åŠæ˜¯å¦éœ€è¦æå‡æˆ–é™çº§é˜Ÿåˆ—。 修改åŽçš„yield函数如下: +``` +修改yield函数 其作用是当当å‰è¿è¡Œçš„进程时间片用完,或者æŸä¸ªè¿›ç¨‹ä¸»åŠ¨è®©å‡º CPU 时,它会将当å‰è¿›ç¨‹ç½®ä¸º RUNNABLE 状æ€ï¼Œå¹¶è§¦å‘调度器æ¥é€‰æ‹©ä¸‹ä¸€ä¸ªåˆé€‚的进程è¿è¡Œã€‚在多级å馈队列(MFQ)调度ä¸ï¼Œyield 需è¦è€ƒè™‘è¿›ç¨‹æ‰€åœ¨çš„é˜Ÿåˆ—çº§åˆ«ï¼Œè¿›ç¨‹çš„æ—¶é—´ç‰‡ä»¥åŠæ˜¯å¦éœ€è¦æå‡æˆ–é™çº§é˜Ÿåˆ—。 +修改åŽçš„yield函数如下: ```c yield(void) @@ -216,12 +217,37 @@ yield(void) queue_tail[p->queue_level] = (queue_tail[p->queue_level] + 1) % NPROC; // 更新尾指针 mlfq[p->queue_level][head] = 0; // 将当å‰é˜Ÿåˆ—çš„ä½ç½®æ¸…空 queue_head[p->queue_level] = (queue_head[p->queue_level] + 1) % NPROC; // 更新头指针 + //如果没有æ¤è¡Œ 进程的time_usedå°±ä¸ä¼šåœ¨æ¯æ¬¡yield被调用时递增 从而导致进程的时间片将永远ä¸ä¼šå¢žåР以åŠè¿›ç¨‹æ— 法被é™çº§ + p->time_used++; // å¦‚æžœæ—¶é—´ç‰‡æœªç”¨å®Œï¼Œå¢žåŠ å·²ç”¨æ—¶é—´ } sched(); release(&p->lock); } ``` - +下é¢ç®€è¦ä»‹ç»ä¸€ä¸‹è¿›ç¨‹è°ƒåº¦è¿‡ç¨‹çš„å·¥ä½œåŽŸç† +##### 1ã€è¿›ç¨‹åˆå§‹åŒ– +当æ“作系统å¯åŠ¨æ—¶ï¼Œè°ƒåº¦å™¨ scheduler() 会首先执行。在一个多级å馈队列系统ä¸ï¼Œå¤šä¸ªé˜Ÿåˆ—会被åˆå§‹åŒ–,æ¯ä¸ªé˜Ÿåˆ—具有ä¸åŒçš„ä¼˜å…ˆçº§å’Œæ—¶é—´ç‰‡é•¿åº¦ã€‚è¿›ç¨‹ä¼šæ ¹æ®å…¶ä¼˜å…ˆçº§è¢«æ”¾å…¥ç›¸åº”的队列。 +##### 2ã€fork() 创建å进程: +当父进程调用 fork() 时,会创建一个新的å进程。父进程和åè¿›ç¨‹å‡ ä¹Žå®Œå…¨ç›¸åŒï¼Œä½†å®ƒä»¬æ˜¯ç‹¬ç«‹çš„进程,拥有å„自的进程控制å—(PCB),并有ä¸åŒçš„进程 ID 和状æ€ã€‚ +在 fork() 调用åŽï¼Œçˆ¶è¿›ç¨‹ä¼šç»§ç»æ‰§è¡Œè‡ªå·±çš„任务,而å进程通常会执行ä¸åŒçš„任务(如果它接下æ¥è°ƒç”¨ exec()),但也å¯ä»¥é€šè¿‡è°ƒç”¨ yield() 或ç‰å¾…调度æ¥è¿›å…¥å¯è¿è¡Œçжæ€ã€‚ +##### 3ã€è°ƒåº¦è¿‡ç¨‹ (scheduler()): +在任何一个进程执行时,它都å¯èƒ½ä¼šè¢«è°ƒåº¦å™¨ scheduler() 选ä¸ã€‚scheduler() 会é历å„个优先级队列(MFQ ä¸çš„队列),查找一个å¯è¿è¡Œçš„进程。 +一旦选择了一个进程,调度器会将其状æ€è®¾ç½®ä¸º RUNNING,并将进程的上下文切æ¢åˆ°è¯¥è¿›ç¨‹ã€‚æ¤æ—¶ï¼Œè¿›ç¨‹å¼€å§‹æ‰§è¡Œã€‚ +##### 4ã€è¿›ç¨‹æ—¶é—´ç‰‡ç”¨å°½æ—¶è°ƒç”¨ yield(): +当进程的时间片耗尽时,进程会调用 yield() æ¥ä¸»åŠ¨è®©å‡º CPU 使用æƒã€‚ +yield() 会先将进程的状æ€è®¾ç½®ä¸º RUNNABLE,然åŽå°†è¿›ç¨‹æ”¾å›žåˆ°å…¶æ‰€åœ¨çš„队列ä¸ï¼ˆå¯èƒ½æ˜¯å½“å‰é˜Ÿåˆ—,也å¯èƒ½æ˜¯é™çº§åˆ°ä¸€ä¸ªæ›´ä½Žä¼˜å…ˆçº§çš„队列)。 +调用 yield() åŽï¼Œscheduler() ä¼šå†æ¬¡è¢«è°ƒç”¨ï¼Œé€‰æ‹©ä¸‹ä¸€ä¸ªè¿›ç¨‹æ‰§è¡Œã€‚ +##### 5ã€yield() 在时间片内使用: +如果进程在时间片未用完时执行 yield()ï¼Œå®ƒä¼šå°†è‡ªå·±é‡æ–°åŠ å…¥é˜Ÿåˆ—å°¾éƒ¨ï¼Œå¹¶ç‰å¾…è°ƒåº¦å™¨é€‰æ‹©ä¸‹ä¸€ä¸ªè¦æ‰§è¡Œçš„进程。 +这个过程ä¸ï¼Œyield() 主è¦ç”¨æ¥åœ¨æŸäº›æƒ…况下主动放弃 CPU 使用æƒï¼Œé¿å…饥饿现象或者让其他进程有机会è¿è¡Œã€‚ +##### 6ã€æ—¶é—´ç‰‡ç»“æŸåŽï¼Œè¿›ç¨‹çŠ¶æ€æ›´æ–°ï¼š +当一个进程的时间片用尽时,yield() å‡½æ•°ä¼šå°†å…¶çŠ¶æ€æ¢å¤ä¸º RUNNABLE,并检查它是å¦å·²ç»è¶…过当å‰é˜Ÿåˆ—的时间片。 +如果时间片用完且进程未完æˆï¼Œå®ƒå°†è¢«é™çº§åˆ°ä¸€ä¸ªæ›´ä½Žä¼˜å…ˆçº§çš„队列。之åŽï¼Œå®ƒä¼šè¢«æ”¾å›žç›¸åº”队列ä¸ï¼Œç‰å¾…调度器的选择。 +##### 7ã€è°ƒåº¦å™¨é€‰æ‹©ä¸‹ä¸€ä¸ªè¿›ç¨‹ï¼š +åœ¨æ¯æ¬¡ yield() 或其他事件导致当å‰è¿›ç¨‹æ”¾å¼ƒ CPU åŽï¼Œscheduler() ä¼šé‡æ–°é€‰æ‹©ä¸‹ä¸€ä¸ª RUNNABLE 状æ€çš„进程。 +进程调度时,scheduler() 会考虑进程的优先级(MLFQ 的队列ç‰çº§ï¼‰ï¼Œå¹¶å†³å®šå“ªä¸ªé˜Ÿåˆ—ä¸çš„进程将被选择。调度器会先选择高优先级队列ä¸çš„进程,确ä¿ä¼˜å…ˆçº§é«˜çš„进程能更多地获得 CPU 时间。 +##### 8ã€å¤„ç†æ–°è¿›ç¨‹ï¼ˆfork() 创建新进程): +任何时候,如果父进程调用 fork(),一个新的å进程会被创建。新创建的å进程会被åˆå§‹åŒ–并被放入æŸä¸ªé˜Ÿåˆ—ï¼ˆæ ¹æ®å…¶ä¼˜å…ˆçº§ï¼‰ã€‚这个å进程会æˆä¸ºä¸€ä¸ªæ–°çš„候选进程,准备进入调度队列,ç‰å¾…调度器选择。 ### 2.2 文件管ç†ç³»ç»Ÿ -- GitLab