OS中阻塞與掛起的區別 sleep 的實現原理

2021-09-29 11:11:17 字數 1511 閱讀 9048

部落格原文

核心的sleep()函式是在掛起原語的基礎上利用定時器實現的。

阻塞與掛起都是程序的狀態,但他們有一些相似之處,也有一些區別,下面先對他們進行概述,再進行比較

阻塞:正在執行的程序由於發生某時間(如i/o請求、申請緩衝區失敗等)暫時無法繼續執行。此時引起程序排程,os把處理機分配給另乙個就緒程序,而讓受阻程序處於暫停狀態,一般將這種狀態稱為阻塞狀態。

掛起:由於系統和使用者的需要引入了掛起的操作,程序被掛起意味著該程序處於靜止狀態。如果程序正在執行,它將暫停執行,若原本處於就緒狀態,則該程序此時暫不接受排程。

共同點

1. 程序都暫停執行

2. 程序都釋放cpu,即兩個過程都會涉及上下文切換

不同點

1. 對系統資源占用不同:雖然都釋放了cpu,但阻塞的程序仍處於記憶體中,而掛起的程序通過「對換」技術被換出到外存(磁碟)中。

2. 發生時機不同:阻塞一般在程序等待資源(io資源、訊號量等)時發生;而掛起是由於使用者和系統的需要,例如,終端使用者需要暫停程式研究其執**況或對其進行修改、os為了提高記憶體利用率需要將暫時不能執行的程序(處於就緒或阻塞佇列的程序)調出到磁碟

3. 恢復時機不同:阻塞要在等待的資源得到滿足(例如獲得了鎖)後,才會進入就緒狀態,等待被排程而執行;被掛起的程序由將其掛起的物件(如使用者、系統)在時機符合時(除錯結束、被排程程序選中需要重新執行)將其主動啟用

之所以將sleep一起討論,是因為sleep是乙個很常見的系統呼叫,在很多程式語言中,也有對應的函式,所以一起討論可以明白sleep的過程與阻塞和掛起在底層的效果又有哪些區別。

sleep():程序、執行緒或任務(linux中不區分程序與執行緒,都稱為task)可以sleep,這會導致它們暫停執行一段時間,直到等待的時間結束才恢復執行或在這段時間內被中斷。

sleep()在os中的實現的大概流程:

-掛起程序(或執行緒)並修改其執行狀態

- 用sleep()提供的引數來設定乙個定時器。

- 當時間結束,定時器會觸發,核心收到中斷後修改程序(或執行緒)的執行狀態。例如執行緒會被標誌為就緒而進入就緒佇列等待排程。

ps:關於第二點在這裡要介紹一些背景知識:可變定時器(variable timer)一般在硬體層面是通過乙個固定的時鐘和計數器來實現的,每經過乙個時鐘週期將計數器遞減,當計數器的值為0時產生中斷。核心註冊乙個定時器後可以在一段時間後收到中斷。

在linux下,sleep()的實現流程大概如下:

#include 

#include

#include

#include

///時鐘程式設計 alarm()

void wakeup()

int main(void)

部落格原文

阻塞和掛起的區別

阻塞 如果乙個任務當前正在等待某個外部事件的話就說它處於阻塞態,比如說如果某個任務調 用了函式 vtaskdelay 的話就會進入阻塞態,直到延時週期完成。任務在等待佇列 訊號量 事 件組 通知或互斥訊號量的時候也會進入阻塞態。任務進入阻塞態會有乙個超時時間,當超過 這個超時時間任務就會退出阻塞態,...

程序的掛起與阻塞

阻塞是由於程序所需資源得不到滿足,並會最終導致程序被掛起 程序掛起的原因並不一定是由於阻塞,也有可能是時間片得不到滿足,掛起狀態是程序從記憶體排程到外存中的一種狀態,若在就緒態時,從記憶體調出到外存中,就是就緒掛起態,若在阻塞態時,從記憶體調出到外存中,就轉換成了阻塞掛起態 掛起 一般是主動的,由系...

linux 區別 掛起 阻塞 阻塞和死迴圈的區別

關於各種任務狀態的實質 1.掛起 將任務掛起的實質就是1 將當前任務控制塊的狀態標誌改為掛起狀態2 將任務就緒表中的對應位置0 3 如果是事件型別,則還會將任務加入到當前的事件等待任務列表中 和就緒表一樣的點陣圖 4 執行任務排程,讓出cpu使用權。這裡需要注意的是,任務掛起後任務不是處於占用cpu...