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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OS中阻塞与挂起的区别sleep()的实现原理

發布時間:2025/6/17 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OS中阻塞与挂起的区别sleep()的实现原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
版權聲明:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。 本文鏈接:https://blog.csdn.net/xpy870663266/article/details/78164506

博客原文

阻塞 VS 掛起

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

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

阻塞:正在執行的進程由于發生某時間(如I/O請求、申請緩沖區失敗等)暫時無法繼續執行。此時引起進程調度,OS把處理機分配給另一個就緒進程,而讓受阻進程處于暫停狀態,一般將這種狀態稱為阻塞狀態。

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

共同點
1. 進程都暫停執行
2. 進程都釋放CPU,即兩個過程都會涉及上下文切換

不同點
1. 對系統資源占用不同:雖然都釋放了CPU,但阻塞的進程仍處于內存中,而掛起的進程通過“對換”技術被換出到外存(磁盤)中。
2. 發生時機不同:阻塞一般在進程等待資源(IO資源、信號量等)時發生;而掛起是由于用戶和系統的需要,例如,終端用戶需要暫停程序研究其執行情況或對其進行修改、OS為了提高內存利用率需要將暫時不能運行的進程(處于就緒或阻塞隊列的進程)調出到磁盤
3. 恢復時機不同:阻塞要在等待的資源得到滿足(例如獲得了鎖)后,才會進入就緒狀態,等待被調度而執行;被掛起的進程由將其掛起的對象(如用戶、系統)在時機符合時(調試結束、被調度進程選中需要重新執行)將其主動激活

sleep()

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

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

OS中sleep()的實現

sleep()在OS中的實現的大概流程:
- 掛起進程(或線程)并修改其運行狀態
- 用sleep()提供的參數來設置一個定時器。
- 當時間結束,定時器會觸發,內核收到中斷后修改進程(或線程)的運行狀態。例如線程會被標志為就緒而進入就緒隊列等待調度。

PS:關于第二點在這里要介紹一些背景知識:可變定時器(variable timer)一般在硬件層面是通過一個固定的時鐘和計數器來實現的,每經過一個時鐘周期將計數器遞減,當計數器的值為0時產生中斷。內核注冊一個定時器后可以在一段時間后收到中斷。

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

#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h>///時鐘編程 alarm() void wakeUp() {printf("please wakeup!!/n"); }int main(void) {printf("you have 4 s sleep!/n");signal(SIGALRM,wakeUp);alarm(4);//將進程掛起pause();printf("good morning!/n");return EXIT_SUCCESS;}
  • 綜上所述,內核的sleep()函數是在掛起原語的基礎上利用定時器實現的。

    調用以下哪些方法可以使運行狀態的線程進入阻塞狀態?( )A.start( ),yield( ),sleep( ),join( )和wait( )B.start( ),yield( ),sleep( ),join( ),wait( )和stop( )C.yield( ),sleep( ),join( )和wait( )D.yield( ),sleep( ),join( ),wait( )和stop( )參考答案 正確答案:C 解析:運行狀態的進程如果調用了yield( )方法、sleep( )方法、 join( )方法或wait( )方法,或者申請對象鎖未果、有更高優先級線程進入調度等, 都可進入阻塞狀態。阻塞狀態的進程在獲取到足夠的資源后 ,也可以轉入到可運行狀態。

    編程語言中sleep()的實現

    首先希望大家都了解用戶線程和內核線程的概念。編程語言中的線程(用戶線程)與內核線程是有著一定的映射關系的。下面以Java為例,解釋一下用戶線程與內核線程的映射關系,不過多涉及實現細節。想要了解用戶線程和內核線程的關系模型,見 線程的三種實現模型

    Java線程API通常使用宿主系統的線程庫來實現,也就是說,在Windows中,Java線程使用Win32 API來實現,而在Linux和Unix系統中使用Pthread。而且,JVM規范并沒有指明Java線程如何被映射到底層的OS,而是讓特定的JVM實現來決定。例如,在Window XP中采用一對一模型,而對于Solaris系統,剛開始采用多對一模型,從Solaris 9開始采用多對多模型。

    看到這里大家應該明白了,用戶線程的sleep()正是利用內核提供的sleep()來實現的,沒有內核的支持,用戶線程也只能忙等直到規定的時間結束。

    參考資料:
    1. 《計算機操作系統(第四版)》,湯子瀛等著
    2. 《操作系統概念(第七版)》,Silberschatz等著,鄭扣根譯
    3. Quora 問答
    4. http://blog.csdn.net/freezgw1985/article/details/5631922
    5. https://en.wikipedia.org/wiki/Sleep_(system_call)
    6. http://man7.org/linux/man-pages/man3/sleep.3.html
    7. http://man7.org/linux/man-pages/man2/nanosleep.2.html
    8. http://man7.org/linux/man-pages/man2/alarm.2.html

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的OS中阻塞与挂起的区别sleep()的实现原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。