本文主要介绍线程的调度激活机制(Scheduler Activations),主要内容:

  1. 调度激活机制简介
  2. 上行调用(upcall)
  3. 中断处理(Interrupt)

一、 调度激活机制简介

上一篇文章详细阐述了用户空间和内核空间的线程实现,各有优劣,内核线程在各方面都比较灵活,但是太慢,性能不高,经常会出现请求在用户空间和内核空间的传递。那么如何在拥有内核空间线程的灵活性的同时又提高性能呢。这就是Scheduler Activations机制要做的事情。

该机制的主要目标是在用户空间模拟内核空间的线程(从灵活性方面),这样在当一个进程内的一个用户线程被block(比如发生缺页异常)时,不会导致整个进程被block,这个进程的内的其他用户线程还可以继续运行(类似于内核线程)。

当Scheduler Activations机制启用时,内核会给每一个进程分配一定数量的CPU(有可能是虚拟的,如果是多核系统,有可能是真实的CPU)。这样每一个进程的运行时系统(run-time system)就可以给自己的线程(user-space threads)分配这些cpu。

  1. 初始默认的cpu数量是1
  2. 进程可以箱内核申请更多的cpu
  3. 进程可以将不再使用的CPU归还给内核
  4. 内核可以自己将不用的CPU自己回收

由此可见,这种机制下,进程对于CPU来说依然还是单线程的,内核依然不知道进程拥有多少线程。示意图如下。

二、上行调用(upcall)

上面阐释了调度激活机制,那么是如何实现的,运行时是如何给自己的线程分配cpu的。如何调度的,这个是通过上行调用(upcall)来完成的。在cpu中用户空间为上层,内核为下层层,常规调用应该是上层调用下层,下层不应该调用上层,upcall就是指内核调用用户空间。

上图展示了upcall。并且用传统应用webui和bll的调用做了类比,upcall是不规范的,但是调度激活就是通过upcall实现的。

upcall具体做了什么?

  1. 内核发现用户进程的一个线程被block了(比如调用了一个被block的system call,或者发生了缺页异常。
  2. 内核通过进程的运行时线程被block(还会告知被block的线程的详细信息),这个就是upcall
  3. 进程的运行时系统接收到内核发来的消息,得知自己的线程被block
  4. 运行时系统先将当前线程标识为block(会保存在线程表-thread table)
  5. 运行时系统从当前线程表(thread table)选择一个ready的线程进行运行

至此已经完成了当一个进程内的一个用户线程被block(比如发生缺页异常)时,不会导致整个进程被block,这个进程的内的其他用户线程还可以继续运行(类似于内核线程)。

当内核发现之前被block的线程可以run了,同样会通过upcall通知运行时系统,运行时系统要么马上运行该线程,要么把该线程标志位ready放入线程表。

三、中断处理

当一个用户线程在运行的时候硬件产生了一个中断(Interrupt),这个时候应该怎么办呢?

  1. 被中断的进程不关注这个中断,这个时候被中断的线程会继续返回到中断产生前的状态继续执行
  2. 被中断的进程关注这个中断,被中断的线程会被挂起,至于运行那个线程:被中断的线程,新的ready线程还是其他线程,这个有运行时系统决定

Operating System-Thread(4) 线程的调度激活机制(Scheduler Activations)的更多相关文章

  1. 41、Thead线程 System.Thread与互斥体Mutex

    Thead线程 System.Thread 使用Thread类可以创建和控制线程.下面的代码是创建和启动一个新线程的简单例子.Thread 类的构造函数重载为接受ThreadStart和Paramet ...

  2. Java多线程-线程的调度(休眠)

    Java线程调度是Java多线程的核心,只有良好的调度,才能充分发挥系统的性能,提高程序的执行效率. 这里要明确的一点,不管程序员怎么编写调度,只能最大限度的影响线程执行的次序,而不能做到精准控制. ...

  3. Java多线程-线程的调度(合并)

    线程的合并的含义就是将几个并行线程的线程合并为一个单线程执行,应用场景是当一个线程必须等待另一个线程执行完毕才能执行时可以使用join方法. join为非静态方法,定义如下:void join(): ...

  4. Java多线程-线程的调度(守护线程)

    本文转自http://www.cnblogs.com/linjiqin/p/3210004.html 感谢作者 守护线程与普通线程写法上基本没啥区别,调用线程对象的方法setDaemon(true), ...

  5. Windows内核之线程的调度,优先级,亲缘性

    1 调度 Windows不是实时操作系统,它是抢占式多线程操作系统.在如果全部优先级同样的情况下,CPU对线程的调度原则是每隔20m就会切换到下一个线程,依据Context中的IP和SP来接着运行上次 ...

  6. Thread类(线程)

    操作系统通过线程对程序的执行进行管理,当操作系统运行一个程序的时候,首先,操作系统将为这个准备运行的程序分配一个进程,以管理这个程序所需要的各种资源.在这些资源之中,会包含一个称为主线程的线程数据结构 ...

  7. Java多线程-线程的调度(让步)

    线程的让步含义就是使当前运行着线程让出CPU资源,但是扔给谁不知道,仅仅是让出,线程状态回到可运行状态. 线程的让步使用Thread.yield()方法,yield()为静态方法,功能是暂停当前正在执 ...

  8. Java多线程-线程的调度(优先级)

    与线程休眠类似,线程的优先级仍然无法保障线程的执行次序.只不过,优先级高的线程获取CPU资源的概率较大,优先级低的并非没机会执行. 线程的优先级用1-10之间的整数表示,数值越大优先级越高,默认的优先 ...

  9. SI - 系统 - 操作系统简述 (Operating System)

    Unix 操作系统:System V.BSD Microsoft Windows Apple Mac OS Linux FreeBSD 安装 https://jingyan.baidu.com/art ...

随机推荐

  1. 九度OJ 1187:最小年龄的3个职工 (排序)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2291 解决:936 题目描述: 职工有职工号,姓名,年龄.输入n个职工的信息,找出3个年龄最小的职工打印出来. 输入: 输入第一行包括1个 ...

  2. Ubuntu 下安装JDK1.8

    好困,不行了,我要睡觉了,先上图吧!

  3. Js版json解析

    JsonDecoder={ pos:0, isDigit:function(ch){ return ( ch >= '0' && ch <= '9' )||( ch == ...

  4. 在函数中如何获取 线程对象、线程唯一ID

    threading.current_thread() threading.current_thread().ident

  5. PAT 1061. 判断题(15)

    判断题的评判很简单,本题就要求你写个简单的程序帮助老师判题并统计学生们判断题的得分. 输入格式: 输入在第一行给出两个不超过100的正整数N和M,分别是学生人数和判断题数量.第二行给出M个不超过5的正 ...

  6. Jquery事件绑定的4中方式对比

    bind()向匹配元素添加一个或多个事件处理器. 使用方式 $(selector).bind(event,data,function) event:必需项:添加到元素的一个或多个事件,例如 click ...

  7. STM32L0 HAL库 TIM定时1s

    STM32L0的定制器资源: 本实验使用TIM6 HSI频率是16Mhz,则单指令周期是1/16Mhz 预分频设置为1600,则每跑1600下,定时器加1,相当于定时器加1的时间是1600*(1/16 ...

  8. shell编程2 ---条件判断语句

    shell编程2 一.条件判断语句 1.按照文件类型进行判断 eg:test -e /etc/passwd  或者  [ -e /etc/passwd ]  &&echo yes || ...

  9. php......房屋租赁练习

    多条件查询搜索页面,提交到当前页面处理 <?php include("../DB.class.php"); $db = new DB(); /*var_dump($_POST ...

  10. c的详细学习(5)数组

        到目前为止,前面介绍的都是属于基本类型的数据.除此之外,C语言还提供了一些更为复杂的数据类型,称为构造类型.数组就是最基本的构造类型.若要针对一批数据进行某种操作,采用数组是一种方便可行的方法 ...