版权声明:本文为博主原创文章,遵循 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

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

  1. 操作系统中阻塞和挂起的区别和联系

    阻塞和挂起是操作系统的进程的状态描述,容易混淆. 阻塞:正在执行的进程由于发生某时间(如I/O请求.申请缓冲区失败等)暂时无法继续执行.此时引起进程调度,OS把处理机分配给另一个就绪进程,而让受阻进程 ...

  2. 进程的阻塞和挂起的区别

    理解一:挂起是一种主动行为,因此恢复也应该要主动完成,而阻塞则是一种被动行为,是在等待事件或资源时任务的表现,你不知道他什么时候被阻塞(pend),也就不能确切 的知道他什么时候恢复阻塞.而且挂起队列 ...

  3. 挂起进程和进程的阻塞和挂起的区别

    挂起进程在操作系统中可以定义为暂时被淘汰出内存的进程,机器的资源是有限的,在资源不足的情况下,操作系统对在内存中的程序进行合理的安排,其中有的进程被暂时调离出内存,当条件允许的时候,会被操作系统再次调 ...

  4. 阻塞和挂起的区别和联系

    阻塞和挂起是进程两种不同的状态,其描述如下: 阻塞:正在执行的进程由于发生某时间(如I/O请求.申请缓冲区失败等)暂时无法继续执行.此时引起进程调度,OS把处理机分配给另一个就绪进程,而让受阻进程处于 ...

  5. JAVA中阻塞队列的类别和区别(转载)

    这篇文章将介绍什么是阻塞队列,以及Java中阻塞队列的4种处理方式,并介绍Java 7中提供的7种阻塞队列,最后分析阻塞队列的一种实现方式. 阻塞队列(BlockingQueue)是一个支持两个附加操 ...

  6. 【原创】uC/OS 中LES BX,DWORD PTR DS:_OSTCBCur的作用及原理

    1 LES BX, DWORD PTR DS:_OSTCBCur ;OSTCBCur->OSTCBStkPtr = SS:SP!!! 2 MOV ES:[BX+2], SS ;将当前SS(栈的基 ...

  7. 嵌入式多任务OS中Vxworks和linux的一些区别

    自己目前开发的嵌入式开发所用的操作系统是VxWorks,以前读大学的时候用的最多的是linux操作系统,但是,对于这两种操作系统之间到底有什么区别,还真没有真正去细心的总结过,被别人问起时,难免有些尴 ...

  8. 线程和进程/阻塞和挂起以及那些sleep,wait()和notify()方法详解

    线程与进程的阻塞 线程阻塞 线程在运行的过程中因为某些原因而发生阻塞,阻塞状态的线程的特点是:该线程放弃CPU的使用,暂停运行,只有等到导致阻塞的原因消除之后才回复运行,或者是被其他的线程中断,该线程 ...

  9. 线程和进程/阻塞和挂起

    曾多次迷惑于阻塞和挂起状态,后来才发现,有一些文章没有区别,把(阻塞.挂起.等待)等同了,这时看语境作者说的是哪个.自己加以分析区别. 先大概这样理解一下: 挂起:一般是主动的,由系统或程序发出,甚至 ...

最新文章

  1. 中通知设置响铃_iOS 13.1.3 正式版:解决来电不响铃问题
  2. 死磕java并发cas_死磕Java——CAS
  3. jscript换行等特殊字符
  4. linux fstab 参数,Linux fstab参数详解
  5. linux sed 笔记
  6. mysql的dockerfile_dockerfile构建mysql镜像
  7. 计算机毕业设计中用Java实现在线考试系统
  8. 骁龙845_性能强大价格更吸引 超值骁龙845手机盘点
  9. jmeter java性能_性能测试十一:jmeter进阶之java请求
  10. KEIL C51出现 runtime error R6002 floating point support not loaded解决办法
  11. 效果图软件选择手册 | Lumion、VRay、Conora、Enscape...你适合用什么软件做效果图?
  12. 奇妙的定律、理论、原则、效应、...(Amazing Laws,Theories,Principles,Effects,...)
  13. camille mumu 模拟器 frida 踩坑记录
  14. 文本分类---逻辑回归(1)
  15. 梯形断面正常水深莫洛图
  16. SEO优化 TDK的写法思路
  17. adb连接夜神模拟器提示:adb unable to connect to 127.0.0.162001 cannot connect to 127.0.0.16200 由于目标 计算机积极拒绝
  18. 蓝桥杯矩形切割python求解
  19. 雷军一往无前的十年(小米十周年公开演讲)附赠《一往无前》电子书籍
  20. 洛谷P2556 [AHOI2002]黑白图像压缩(简单模拟题)

热门文章

  1. ubuntu “快捷方式”
  2. 《算法进阶指南》最小生成树剩余题目
  3. Node.js 把图片流送到客户端
  4. 苏宁易购11.11:商品详情系统架构设计
  5. DELL服务器引导光盘图片及下载链接
  6. 字符的点阵显示(模拟户外广告显示屏)
  7. POJ3687拓扑排序+贪心
  8. POJ2349二分+并查集,类似最小树的贪心
  9. UVA11292杀怪
  10. 解决vue-awesome-swiper中swiper/css/swiper.css无法导入问题