xv6 中的一些系統調用(下)

〇、前言

本文將會結合源代碼談論 sleepwakeup 這兩個系統調用。

一、sleep()系統調用

以下是sleep()函數源碼:

// Atomically release lock and sleep on chan.
// Reacquires lock when awakened.
void
sleep(void *chan, struct spinlock *lk)
{struct proc *p = myproc();// Must acquire p->lock in order to// change p->state and then call sched.// Once we hold p->lock, we can be// guaranteed that we won't miss any wakeup// (wakeup locks p->lock),// so it's okay to release lk.acquire(&p->lock);  //DOC: sleeplock1release(lk);// Go to sleep.p->chan = chan;p->state = SLEEPING;sched();// Tidy up.p->chan = 0;// Reacquire original lock.release(&p->lock);acquire(lk);
}

先來看看 lost wakeup 問題。當一個進程在 sleep() 時,如果 sleep() 了一半,狀態還沒來得及修改為SLEEPING,這時候發生了中斷,并且被某些進程調用了 wakeup(),那么這個 wakeup()肯定不能把這個進程喚醒。而且,在被中斷恢復后,它將永遠等不到喚醒,因為喚醒已經錯過。所以,在這里必須要正不可中斷性操作先后性。因為在下面就會看到 wakeup() 只喚醒狀態為 SLEEPING 的進程。

因此我們必須保證,sleep() 是一個原子操作,在 sleep() 執行過程中,要么執行完全,要么沒有被執行。所以這里必須加一個進程鎖。所以在下面就會看到 wakeup() 中也會嘗試獲取休眠的進程鎖。

在持有進程鎖的時候,將進程的狀態設置為 SLEEPING 并記錄sleep channel,之后再調用 sched() 函數,這個函數中會再調用 swtch() 函數(而這會返回到 scheduler()函數中),此時 sleep() 函數中仍然持有了進程的鎖,wakeup() 仍然不能做任何事情。

因此在 sleep()之后,這個鎖必須釋放。我們來看看細節:

void
scheduler(void)
{...swtch(&c->context, &p->context);// Process is done running for now.// It should have changed its p->state before coming back.c->proc = 0; // 返回的位置,此刻繼續執行}release(&p->lock);...
}

在這里,它會繼續執行上一次執行到的位置,即 c->proc = 0,然后執行 release(&p->lock),也就是釋放鎖,而且釋放的是 sleep() 中的當前進程的鎖。(這一點不是很好理解,可以理解為用的上一個進程的代碼釋放當前進程的鎖?總之,這些代碼就冰冷冷的放在內存里,被 pc 不斷地指一遍又一遍)。更有意思的是,在 sched() 函數返回之后,繼續運行:

void
sleep(void *chan, struct spinlock *lk)
{...sched();// Tidy up.p->chan = 0; // 就緒執行的位置// Reacquire original lock.release(&p->lock);acquire(lk);
}

這里 release(&p->lock) 實際上釋放的是 scheduler() 中選中的進程的鎖。

所以在調度器線程釋放進程鎖之后,wakeup() 才能終于獲取進程的鎖,發現它正在 SLEEPING狀態,并喚醒它。

這里的效果是由之前定義的一些規則確保的,這些規則包括了:

  • 調用 sleep 時需要持有condition lock,這樣 sleep 函數才能知道相應的鎖;
  • sleep函數只有在獲取到進程的鎖 p->lock之后,才能釋放 condition lock
  • wakeup需要同時持有兩個鎖才能查看進程。

二、wakeup()調用

以下是 wakeup() 的源碼:

// Wake up all processes sleeping on chan.
// Must be called without any p->lock.
void
wakeup(void *chan)
{struct proc *p;for(p = proc; p < &proc[NPROC]; p++) {if(p != myproc()){acquire(&p->lock);if(p->state == SLEEPING && p->chan == chan) {p->state = RUNNABLE;}release(&p->lock);}}
}

可以看到它的工作很簡單,檢查兩個條件之后,就修改進程的狀態為 RUNNABLE

三、總結

這篇文章詳細地介紹了 xv6 操作系統中的 sleep()wakeup() 系統調用的實現原理以及相關的內部工作機制。主要強調了在 sleep() 中的原子操作性,確保了操作的完整性,以及在 wakeup() 中喚醒休眠進程的方式。

關于 sleep()

強調了 sleep() 操作的原子性,使用進程鎖確保 sleep() 操作是一個原子操作,避免了 “lost wakeup” 問題的發生。
通過釋放持有的鎖,讓出 CPU 控制權,進入 SLEEPING 狀態,然后釋放進程鎖,使得其他進程能夠繼續運行。
調度器在合適的時機恢復了進程的執行,完成 sleep() 操作。

關于 wakeup()

wakeup() 通過遍歷進程列表,并獲取每個進程的鎖,查看處于 SLEEPING 狀態且 sleep channel 匹配的進程,將其狀態設置為 RUNNABLE,喚醒進程。

整體上,這篇文章清晰地解釋了 sleep()wakeup() 這兩個關鍵系統調用的工作原理和實現細節,突出了在并發環境下確保原子性操作和避免死鎖的重要性。

全文完,感謝閱讀。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/213733.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/213733.shtml
英文地址,請注明出處:http://en.pswp.cn/news/213733.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

無線且列窄圖片如何轉excel?

寫此文原因&#xff1a;圖片要轉excel&#xff0c;這放以前&#xff0c;是不能實現的功能&#xff0c;但隨著人工智能的蓬勃發展&#xff0c;人們已克服了這一難題&#xff0c;但是&#xff0c;我們知道&#xff0c;要將圖片識別成excel&#xff0c;識別程序首先要先識別圖片中…

如何在小米路由器4A千兆版刷入OpenWRT并通過內網穿透工具實現公網遠程訪問

文章目錄 前言1. 安裝Python和需要的庫2. 使用 OpenWRTInvasion 破解路由器3. 備份當前分區并刷入新的Breed4. 安裝cpolar內網穿透4.1 注冊賬號4.2 下載cpolar客戶端4.3 登錄cpolar web ui管理界面4.4 創建公網地址 5. 固定公網地址訪問 前言 OpenWRT是一個高度模塊化、高度自…

交易歷史記錄20231206 記錄

昨日回顧&#xff1a; select top 10000 * from dbo.CODEINFO A left join dbo.全部&#xff21;股20231206010101 B ON A.CODE B.代碼 left join dbo.全部&#xff21;股20231206CONF D on A.CODED.代碼left join dbo.全部&#xff21;股20231206 G on A.CODEG.代碼 left…

解決前端跨域問題,后端解決方法

Spring CloudVue前后端分離項目報錯&#xff1a;Network Error&#xff1b;net::ERR_FAILED&#xff08;請求跨越&#xff09;-CSDN博客記錄自用

Kafka-快速實戰

Kafka介紹 ChatGPT對于Apache Kafka的介紹&#xff1a; Apache Kafka是一個分布式流處理平臺&#xff0c;最初由LinkedIn開發并于2011年開源。它主要用于解決大規模數據的實時流式處理和數據管道問題。 Kafka是一個分布式的發布-訂閱消息系統&#xff0c;可以快速地處理高吞吐…

阿里云國際基于CentOS系統鏡像快速部署Apache服務

阿里云輕量應用服務器提供了Windows Server系統鏡像和主流的Linux系統鏡像&#xff0c;您可以通過該類鏡像創建純凈、安全、穩定的運行環境。本文以CentOS 7.6系統鏡像為例&#xff0c;介紹如何快速配置Apache服務。 背景信息 注意&#xff0c;阿里云國際通過corebyt注冊并充…

使用rawpy.imread讀取.RAW格式數據和.dng格式數據(附代碼)

.dng格式是一個更兼容、更高效的RAW格式。如果需要在不同軟件之間交換RAW文件&#xff0c;或者需要在軟件中進行大量編輯&#xff0c;那么.dng格式是一個不錯的選擇。 目錄 一、 .dng格式數據和.RAW格式數據二、 .dng格式數據和.RAW格式數據區別三、安裝rawpy包四、讀取.dng格式…

Flask應用基礎入門總結

【1】使用migrate方式進行數據庫連接 使用migrate方式進行數據庫連接需要在終端分別運行三行代碼&#xff1a; #init&#xff08;運行一次即可&#xff09;&#xff08;此db為自己設置的連接數據庫的對象,可以修改&#xff09; flask db init #&#xff08;將orm模型生成遷移…

從零開始搭建企業管理系統(四):集成 Knife4j

集成 Knife4j 前言Knife4j是什么集成 Knife4j引入 pom 依賴添加基礎配置啟動程序測試完善文檔信息編寫配置類修改 UserController修改 UserEntity修改 BaseEntity 文檔效果圖swagger 界面knife4j 界面 前言 前面一小節我們使用postman來進行接口的調試&#xff0c;如果接口一多…

游戲王的題解

目錄 原題&#xff1a; 時間&#xff1a;1s 空間&#xff1a;256M 題目描述 輸入格式 輸出格式 樣例輸入 樣例輸出 題目大意&#xff1a; 主要思路&#xff1a; dp轉移&#xff1a; dp初始化&#xff1a; 代碼&#xff1a; 原題&#xff1a; 時間&#xff1a;1s …

springboot集成knife4j詳細教程

使用原生的swagger作為接口文檔&#xff0c;功能不夠強大&#xff0c;并且默認的ui比較簡陋&#xff0c;不符合大眾審美。所以實際開發中推薦使用knife4j對swagger進行增強。knife4j的地址&#xff1a;https://gitee.com/xiaoym/knife4j 基本使用 想要使用knife4j非常簡單&…

深入學習Redis:從入門到實戰

Redis快速入門 1.初識Redis1.1.認識NoSQL1.1.1.結構化與非結構化1.1.2.關聯和非關聯1.1.3.查詢方式1.1.4.事務1.1.5.總結 1.2.認識Redis1.3.安裝Redis1.3.1.依賴庫1.3.2.上傳安裝包并解壓1.3.3.啟動1.3.4.默認啟動1.3.5.指定配置啟動1.3.6.開機自啟 1.4.Redis桌面客戶端1.4.1.R…

【VS Code開發】使用Live Server搭建MENJA小游戲并發布至公網遠程訪問

文章目錄 前言1. 編寫MENJA小游戲2. 安裝cpolar內網穿透3. 配置MENJA小游戲公網訪問地址4. 實現公網訪問MENJA小游戲5. 固定MENJA小游戲公網地址 前言 本篇教程&#xff0c;我們將通過VS Code實現遠程開發MENJA小游戲&#xff0c;并通過cpolar內網穿透發布到公網&#xff0c;分…

C++ //習題3.8 寫出下面各邏輯表達式的值。設a=3,b=4,c=5。

C程序設計 &#xff08;第三版&#xff09; 譚浩強 習題3.8 習題3.8 寫出下面各邏輯表達式的值。設a3&#xff0c;b4&#xff0c;c5。 (1) a b > c && b c (2) a || b c && b - c (3) !(a > b) && !c || 1 (4) !(x a) && (y b…

FastAPI之響應狀態碼

使用FastAPI自定義響應狀態碼 FastAPI 是一個現代、快速的 web 框架&#xff0c;用于構建API服務&#xff0c;它允許你通過Python 3.6及以上版本進行編程。一個重要的API設計是返回合適的響應狀態碼&#xff0c;這可以使得客戶端理解服務端的處理結果。本教程將向你展示如何在…

推出 Amazon EC2 C7i 實例

亞馬遜云科技宣布全面推出由定制的第 4 代英特爾至強可擴展處理器&#xff08;代號為 Sapphire Rapids&#xff09;提供支持的 Amazon Elastic Compute Cloud (Amazon EC2) C7i 實例。這些定制處理器僅在亞馬遜云科技上可用&#xff0c;與其他云提供商使用的基于 x86 的同類英特…

Kafka事務是怎么實現的?Kafka事務消息原理詳解

目錄 一、Kafka事務性消息1.1 介紹Kafka事務性消息1.2 事務性消息的應用場景1.3 Kafka事務性消息的優勢 二、Kafka事務性消息的使用2.1 配置Kafka以支持事務性消息生產者配置消費者配置 2.2 生產者&#xff1a;發送事務性消息創建Kafka生產者開始事務發送消息提交或中止事務 2.…

logstash之grok插件自定義規則學習

文章目錄 1、前言2、Grok提供的常用Patterns說明及舉例2.1 常用的表達式說明 3、使用grok插件進行日志字段處理4、案例1&#xff1a;處理nginx的日志4.1、查看nginx日志格式4.2、對nginx的日志進行過濾處理 5、案例2&#xff1a;處理tomcat的日志5.1、[安裝logstash-filter-mul…

外包干了3個月,技術退步明顯.......

先說一下自己的情況&#xff0c;大專生&#xff0c;18年通過校招進入武漢某軟件公司&#xff0c;干了接近4年的功能測試&#xff0c;今年年初&#xff0c;感覺自己不能夠在這樣下去了&#xff0c;長時間呆在一個舒適的環境會讓一個人墮落! 而我已經在一個企業干了四年的功能測…