当前位置: 首页 > news >正文

【多线程】线程休眠(Thread Sleep)的底层实现

【多线程】线程休眠(Thread Sleep)的底层实现

线程休眠的底层实现涉及从用户态到内核态的复杂交互。下面我将分层次、详细地解释其原理。

核心思想

线程休眠的本质是:将线程从“就绪队列”中移除,并将其放入一个“等待队列”,然后主动触发调度,让出CPU给其他线程使用。当休眠条件满足(例如时间到期)后,线程再被重新放回“就绪队列”,等待被调度执行。


实现层次拆解

我们可以从三个层面来理解:

1. 编程语言层面(以Java的 Thread.sleep() 为例)

当你调用 Thread.sleep(millis) 时,这只是一个本地方法(Native Method)的声明。

public static native void sleep(long millis) throws InterruptedException;

它的实际实现是在JVM的C/C++代码中。JVM会对这个调用进行一些初步检查(比如参数是否为正数),然后调用操作系统提供的相应API

2. 操作系统层面(以Linux为例)

这是实现的核心。操作系统通过系统调用 来提供服务。线程休眠主要涉及两个系统调用:

  • nanosleep()clock_nanosleep(): 用于高精度的睡眠。
  • select()poll()epoll(): 当指定超时时间时,也可以实现睡眠。

nanosleep() 为例,其内部实现流程如下:

  1. 参数检查与转换: 系统调用首先检查用户传入的时间参数是否有效(例如不能为负数)。
  2. 设置进程状态: 操作系统内核将当前线程(在Linux中,线程是轻量级进程LWP)的状态从 TASK_RUNNING(运行/就绪)修改为 TASK_INTERRUPTIBLE(可中断睡眠状态)或 TASK_UNINTERRUPTIBLE(不可中断睡眠状态)。对于睡眠操作,通常是 TASK_INTERRUPTIBLE,意味着它可以被信号唤醒。
  3. 启动高精度定时器: 内核会为该线程创建一个高精度定时器,并设置到期时间为当前时间加上休眠时间。
  4. 加入等待队列: 将该线程加入到内核管理的一个“等待队列”中。这个队列与定时器相关联。
  5. 主动调度: 调用 schedule() 函数,主动放弃CPU。这时,内核会从就绪队列中选择另一个就绪的线程来运行。
  6. 休眠等待中…: CPU此时已经在执行其他任务。当前线程处于“冻结”状态,不消耗CPU时间片。

唤醒过程:

  1. 定时器到期: 当预设的休眠时间到达后,硬件时钟(例如APIC定时器)会产生一个中断。
  2. 中断处理: CPU响应中断,执行定时器中断处理程序。
  3. 回调函数: 定时器中断处理程序会遍历所有到期的定时器,并执行其关联的回调函数。
  4. 唤醒线程: 这个回调函数的作用就是将之前休眠的线程从“等待队列”中移除,并将其状态重新设置为 TASK_RUNNING,从而将其放回“就绪队列”。
  5. 重新调度: 此时,该线程已经就绪。在下次调度器运行时(可能在当前时间片用完时),它就有机会被再次选中并分配CPU,从而从 schedule() 函数之后继续执行。
3. 硬件层面
  • 高精度时钟源: 现代计算机都有一个高精度的时钟硬件,如时间戳计数器、HPET等。它为内核定时器提供精确的时间基准。
  • 中断机制: 时钟硬件能够在特定时间点产生中断信号,通知CPU“时间到了”。这是唤醒休眠线程的最终触发信号。

关键数据结构

  • 任务结构体: 在Linux内核中,每个线程/进程都由一个 task_struct 结构体表示,其中有一个 state 字段来记录其当前状态(运行、睡眠等)。
  • 等待队列: 一个链表结构,用于链接所有等待特定事件(如定时器到期)的线程。
  • 高精度定时器: 内核中的 hrtimer 结构,支持纳秒级精度,是实现 sleepnanosleep 的基础。

流程图解

用户线程操作系统内核硬件调用 sleep(n) 系统调用1. 进入内核态a. 设置线程状态为 TASK_INTERRUPTIBLEb. 创建并启动一个n秒的hrtimerc. 将线程加入定时器等待队列调用 schedule(),主动放弃CPU线程被挂起,不消耗CPU等待定时器中断调度并执行其他就绪线程par[休眠等待][其他任务运行]定时器到期,产生中断中断处理程序执行触发定时器回调函数回调函数:将线程状态设为 TASK_RUNNING并将其移回就绪队列线程变为就绪状态下次调度时,选择该线程执行从schedule()返回,恢复执行2. 返回用户态sleep()调用返回,继续执行后续代码用户线程操作系统内核硬件

总结与要点

  1. 协作式: 休眠是线程主动、协作式的行为,它自愿让出CPU。
  2. 系统调用: 休眠必须通过系统调用陷入内核,由内核来操作调度器。
  3. 状态切换: 核心是线程状态的改变:RUNNING -> SLEEPING -> RUNNING
  4. 定时器与中断: 依赖硬件定时器和中断机制来实现精确的时间测量和唤醒。
  5. 不消耗CPU: 休眠的线程在等待期间完全不占用CPU资源,这与忙等待有本质区别。

理解线程休眠的底层实现,是理解操作系统如何进行多任务调度和资源管理的关键一步。

http://www.dtcms.com/a/443400.html

相关文章:

  • 徐州网站建设哪家好薇商城网站建设开发多少钱
  • 网站结算系统怎么做制作网页时一般需要兼容哪些浏览器
  • 郑州哪有做网站的公司各种网站
  • 贵阳网站开发多少钱黄埔做网站要多少钱
  • 尖塔游戏:二分答案
  • ps做网站分辨率自适应西安建设市场诚信信息平台网站
  • 免费提供网站建设设立公司流程以及需要的资料
  • 10.4交作业
  • 南京做网站南京乐识专心义乌做网站
  • 朋友圈营销企业整站seo
  • 网站手机版下悬浮条怎么做做美食网站需求分析报告
  • 京东Java后台开发面试题及参考答案(下)
  • error 403 网站拒绝显示南京外贸网站建站
  • 网站做可以退款吗网站建设要点
  • AutowiredAnnotationBeanPostProcessor执行原理分析
  • 易营宝智能建站免费推广网站
  • html做游戏网站昆明网站设计报价
  • 国科信息学薪火计划模拟赛Round2题解
  • 一文讲通JS普通函数与箭头函数的区别
  • 如何学好电脑维修,想学电脑维修技术去哪里学?
  • 4s店网站建设计划手机微网站平台登录入口
  • [Linux基础——Lesson11.Shell运行原理 (王婆传媒) ]
  • 网站开发工程师任职要求设计app界面的软件
  • 网站更换域名 换程序 SEO沧州做网站的大公司
  • 网站建设与管理教学计划企信网是干什么的
  • 苍溪县建设局网站天元建设集团有限公司是什么性质
  • 企业网站建设与实施调查报告有什么好字体可以导入wordpress
  • seo工作流程图优化建站
  • algorithm <B> data access in array 2/99
  • Kubernetes网络核心:CNI超简指南