Cpu是如何选择线程的?
Cpu是如何选择线程的?
linux中线程存放格式
linux中线程与进程对应的结构体都是task_struct
唯一不同的点在于线程存放的东西少了点(由于一个进程中的线程们是共享一定数据的那些东西就直接存在进程了,如内存地址空间、代码段、文件描述符等),之后将task_struct称为任务
优先级
linux中任务的优先级跨度为0~139,大致分为两大类(记好了,是两大类,与之后调用类是3种有区别):
- 实时任务
- 普通任务
优先级越低,执行顺序越优先
0-99为实时任务
100-139为普通任务
调用类
共分为3大类(目的是为了让linux中的高优先级任务优先执行):

deadline与realtime都是针对实时任务的,于是调用类为3类,而优先级大体分两类
SCHED_DEADLINE:是根据dealine来决定调用优先级的,
即哪个快要超时了,cpu则先选哪个
SCHED_FIFO: 先到先调用嘛,队列思想
SCHED_RR: (有点忘了)对于相同优先级的任务,轮流着运行,每个任务都有一定的时间片,当用完时间片且为执行完会被放回队尾,以保证相同优先级任务的公平性,但高优先级的可插队(可抢占低优先级的任务)
Fair调度类:应用于普通任务,均由CFS调度器管理
我们之前谈到的deadline以及realtime也是由于对应的调度器来管理?
调度器如何同时兼并多种调度策略
- SCHED_NORMAL:普通任务使用的调度策略;
- SCHED_BATCH:后台任务的调度策略,不和终端进行交互,因此在不影响其他需要交互的任务,可以适当降低它的优先级。
完全公平调度
Linux 里面,实现了一个基于 CFS 的调度算法,也就是完全公平调度(Completely Fair Scheduling)。
他的思想是给每个task一个对应的时间(vruntime(这是一个假设你task运行的时间,随着这个task不断被选中运行,他的vruntime也会不断增加,(到时候我们选会优先选择时间更少的,这才公平嘛))),当然即使是面向普通任务,不同优先级的task的分配时间也各有不同(别忘了,我们是分成实时任务与普通任务两大类,他们之间的优先级多了去了)
vruntime的计算公式为:
vruntime+=实际运行时间*优先级(与nice值有关)
这很符合我们的原意,毕竟我们是根据vruntime时间越少的越优先嘛
运行队列
每个核中的都有着对应的运行队列
运行队列中包括三个调用类对应的运行队列
cfs_rq是用红黑树来描述的,按vruntime大小来排序,最左侧的叶子节点,就是下次会被调用的任务
在运行队列选择哪个任务来执行中,仍然会先考虑调用类的优先级:dl>rt>fair,之后再去由其中的内部运行队列接着决定,正是由此才使得"实时任务优于普通任务"
调整优先级
如果调整普通任务优先级的话
启动任务,没有指定优先级,默认为普通任务
如果想在普通任务这个大类中调整局部优先级的话,
那就得用nice值了,nice的设置范围为:-20~19,这是一个偏移量(或者如小林哥说的修正数值),它与优先级(priority)的关系是这样的:priority(new) = priority(old) + nice。
至于取值范围正是限制在调整完依旧是普通任务:
并且这指明了一个点:最终导致运行时间改变的还是优先级
具体看图则了解:

启动任务的时候,指定 nice 的值,比如将 mysqld 以 -3 优先级:

修改已经运行中的任务的优先级,使用 renice 来调整 nice 值:

如果想把普通任务调整成实时任务的话

-f代表fifo
如果-rr则代表rr
参考
小林的博客
Cpu是如何选择线程的?的更多相关文章
- 根据CPU核心数确定线程池并发线程数
一.抛出问题 关于如何计算并发线程数,一般分两派,来自两本书,且都是好书,到底哪个是对的?问题追踪后,整理如下: 第一派:<Java Concurrency in Practice>即&l ...
- 转 根据CPU核心数确定线程池并发线程数
转自: https://www.cnblogs.com/dennyzhangdd/p/6909771.html?utm_source=itdadao&utm_medium=referral 目 ...
- 根据CPU核心数确定线程池并发线程数(转)
一.抛出问题 关于如何计算并发线程数,一般分两派,来自两本书,且都是好书,到底哪个是对的?问题追踪后,整理如下: 第一派:<Java Concurrency in Practice>即&l ...
- Jstack定位CPU使用最多的线程及代码
jstack可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码,所以它在JVM性能调优中使用得非常多.下面我们来一个实例找出某个Java进程中最耗费CPU的Java线程并定位堆栈信息,用到的命令有 ...
- 如何查看服务器CPU核心数和线程数
知道服务器CPU型号,那么我们如何在服务器里面查看服务器CPU核心数和线程数呢? 步骤: 先用鼠标右键点击屏幕最下方的任务栏空白处.会弹出一个菜单. 在菜单中用鼠标左键点选“启动任务管理器”. 点击任 ...
- 如何定位占用cpu过高的线程
如何定位占用cpu过高的线程 近来发现平台应用响应越来越慢,通过top命令发现,cpu占用率越来越高 1. 首先根据top命令,发现占用cpu最高的进程PID:3075. 通过ps aux | gre ...
- 根据CPU核数合理设置线程池大小
一般来说池中总线程数是核心池线程数量两倍,只要确保当核心池有线程停止时,核心池外能有线程进入核心池即可. 我们所需要关心的主要是核心池线程的数量该如何设置. 自定义线程池代码 package com. ...
- Linux排查java程序占用cpu过高的线程代码
分几步骤: 1.通过top,查出占用CPU过高的java进程 ,比如: pid :6666 2.通过ps -mp 6666 -o THREAD,tid,time| sort -n -k1 -r 查看此 ...
- CPU | 物理 CPU vs 逻辑 CPU vs 核心 vs 线程 vs Socket
当我们试着通过 Linux 命令 nproc 和 lscpu 了解一台计算机 CPU 级的架构和性能时,我们总会发现无法正确地理解相应的结果,因为我们会被好几个术语搞混淆:物理 CPU.逻辑 CPU. ...
- 找到占用CPU最高的Java线程
一.找到java进程id jps查看当前运行的java进程id [root@localhost ~]# jps 18354 Jps 9381 Bootstrap 二.找到内存和CPU占用最高的线程pi ...
随机推荐
- C#将日期格式化为指定格式
private void btn_GetTime_Click(object sender, EventArgs e) { lab_time.Text = DateTime.Now.ToString(& ...
- 解决JedisConnectionException的方法
使用maven连接redis,报JedisConnectionException错误,如下: 解决方案: 找到对应启动的redis.conf文件 1.设置bind配置,已注释 2.设置protecte ...
- java进阶(16)--System常用方法总结
一.Systen.out静态变量 静态变量,用的最多的是调用print方法 二.System.out.println() println()其实是printStream类的方法 三.Sytem ...
- java项目实战-jdbc实现-书城的增删改查-day21
目录 1. 安装mysql 安装navicate 2. jdbc实现增删改查 1. 安装mysql 安装navicate 参考网上资料 创库 创表 并放入3条测试数据 2. jdbc实现增删改查 bo ...
- 15-Verilog Coding Style
Verilog Coding Style 1.为什么需要Coding Style 可综合性 - 代码需要综合成网表,如果写了一些不可综合的代码,会出现错误 可读性,代码通常有多个版本,所以需要保证代码 ...
- [转帖]全表扫描却产生大量db file sequential read一例
老熊 Oracle性能优化 2012-05-23 开发人员在进行新系统上线前的数据校验测试时,发现一条手工执行的SQL执行了超过1小时还没有返回结果.SQL很简单: SELECT * FROM MOB ...
- [转帖]ESX/ESXi 主机上的每个插槽中安装了多少内存
https://www.cnblogs.com/reachos/p/11242302.html 要确定在 ESX/ESXi 主机上的每个插槽中安装了多少内存,请执行以下操作: 1. 启动ssh服务 2 ...
- [转帖]Kubernetes-18:Dashboard安装及使用
https://www.cnblogs.com/v-fan/p/13950268.html Helm安装Dashboard 简介 Dashboard 是 kubernetes 的图形化管理工具,可直观 ...
- [转帖]Linux中find命令使用示例
https://zhuanlan.zhihu.com/p/99170116 Linux查找命令是类Unix操作系统中最重要且最常用的命令行实用程序之一. 查找命令可以根据你设定的参数匹配的文件指定的条 ...
- [转帖]kafka漏洞升级记录,基于SASL JAAS 配置和 SASL 协议,涉及版本3.4以下
攻击者可以使用基于 SASL JAAS 配置和 SASL 协议的任意 Kafka 客户端,在对 Kafka Connect worker 创建或修改连接器时,通过构造特殊的配置,进行 JNDI 注入. ...