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 ...
随机推荐
- var _ I = (*T)(nil)
学习的时候看到这样一行代码 var _ Codec = (*GobCodec)(nil) 查了一下后,得到该语句的作用为:检查GobCodec这个结构体是否实现了Codec这个接口 空白标识符_代表变 ...
- VCODE修改控制台编码格式解决输出乱码问题
中文的windows下的cmd默认使用GBK的编码,敲代码时,页面使用的是UTF-8(65001),而powershell控制台默认使用的是GBK编码(936),用chcp命令可以查看.乱码主要是 ...
- vue异步组件
- 万字血书Vue-Vue进阶
Vue进阶 生命周期 组件运行的过程 组件的生命周期是:组件从创建->运行(渲染)->销毁的整个过程,是一个时间段 如何监听组件的不同时刻 vue框架为组件内置了不同时刻的生命周期函数,是 ...
- 如何使用Markdown编写笔记
Markdown是什么? Markdown 是一种轻量级标记语言,创始人为约翰·格鲁伯(John Gruber). 它允许人们使用易读易写的纯文本格式编写文档,然后转换成有效的 XHTML(或者HTM ...
- MPC 是下一代私钥安全的7大原因
PrimiHub一款由密码学专家团队打造的开源隐私计算平台,专注于分享数据安全.密码学.联邦学习.同态加密等隐私计算领域的技术和内容. 多重签名钱包与单一密钥钱包相比,因其提升了资产安全性,如今已成为 ...
- web - 解决 formdata 打印空对象
获取单个值可以使用formData对象.get();而直接打印是看不到的.因为外界访问不到,你使用append方法后,对应的键值对就已经添加到表单里面了,你在控制台看到的是FormData原型,存储的 ...
- Cloudquery的学习安装与使用
Cloudquery的学习安装与使用 下载 官方下载地址: https://www.cloudquery.club/download https://pan.baidu.com/s/1a7XOrnMU ...
- [转帖]docker(一):docker pull指定运行平台架构
https://zhuanlan.zhihu.com/p/539888862 1.概述 大家好,我是欧阳方超.某日要在服务器上部署docker服务,其中要用到nginx,nginx经过pull.sav ...
- [转帖]060-轻量级基于curl的seafile上传脚本
https://anjia0532.github.io/2021/04/07/seafile-client-curl/ 这是坚持技术写作计划(含翻译)的第 60 篇,定个小目标 999,每周最少 2 ...