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是如何选择线程的?的更多相关文章

  1. 根据CPU核心数确定线程池并发线程数

    一.抛出问题 关于如何计算并发线程数,一般分两派,来自两本书,且都是好书,到底哪个是对的?问题追踪后,整理如下: 第一派:<Java Concurrency in Practice>即&l ...

  2. 转 根据CPU核心数确定线程池并发线程数

    转自: https://www.cnblogs.com/dennyzhangdd/p/6909771.html?utm_source=itdadao&utm_medium=referral 目 ...

  3. 根据CPU核心数确定线程池并发线程数(转)

    一.抛出问题 关于如何计算并发线程数,一般分两派,来自两本书,且都是好书,到底哪个是对的?问题追踪后,整理如下: 第一派:<Java Concurrency in Practice>即&l ...

  4. Jstack定位CPU使用最多的线程及代码

    jstack可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码,所以它在JVM性能调优中使用得非常多.下面我们来一个实例找出某个Java进程中最耗费CPU的Java线程并定位堆栈信息,用到的命令有 ...

  5. 如何查看服务器CPU核心数和线程数

    知道服务器CPU型号,那么我们如何在服务器里面查看服务器CPU核心数和线程数呢? 步骤: 先用鼠标右键点击屏幕最下方的任务栏空白处.会弹出一个菜单. 在菜单中用鼠标左键点选“启动任务管理器”. 点击任 ...

  6. 如何定位占用cpu过高的线程

    如何定位占用cpu过高的线程 近来发现平台应用响应越来越慢,通过top命令发现,cpu占用率越来越高 1. 首先根据top命令,发现占用cpu最高的进程PID:3075. 通过ps aux | gre ...

  7. 根据CPU核数合理设置线程池大小

    一般来说池中总线程数是核心池线程数量两倍,只要确保当核心池有线程停止时,核心池外能有线程进入核心池即可. 我们所需要关心的主要是核心池线程的数量该如何设置. 自定义线程池代码 package com. ...

  8. Linux排查java程序占用cpu过高的线程代码

    分几步骤: 1.通过top,查出占用CPU过高的java进程 ,比如: pid :6666 2.通过ps -mp 6666 -o THREAD,tid,time| sort -n -k1 -r 查看此 ...

  9. CPU | 物理 CPU vs 逻辑 CPU vs 核心 vs 线程 vs Socket

    当我们试着通过 Linux 命令 nproc 和 lscpu 了解一台计算机 CPU 级的架构和性能时,我们总会发现无法正确地理解相应的结果,因为我们会被好几个术语搞混淆:物理 CPU.逻辑 CPU. ...

  10. 找到占用CPU最高的Java线程

    一.找到java进程id jps查看当前运行的java进程id [root@localhost ~]# jps 18354 Jps 9381 Bootstrap 二.找到内存和CPU占用最高的线程pi ...

随机推荐

  1. uni-app项目打包成H5部署到服务器(超详细步骤)

    https://blog.csdn.net/weixin_49577940/article/details/118058899?spm=1001.2101.3001.6650.1&utm_me ...

  2. vue中mixin作用

  3. [TSG@Site开发日志3]从C#到Qt,再从Qt到C# 和 Qt的组合开发,浅谈在采集端工控设备开发中不同技术之间选型的利与弊

    [TSG开发日志3]从C#到Qt,再从Qt到C#,浅谈不同技术之间选型的利与弊 当前在South公司的开发历经了几个时代,第一个时代是用C#进行的开发,第二个时代是从C#向Qt逐渐转型,第三个时代是我 ...

  4. distributor和gateway联合实现出中继的负载均衡+故障转移

    概述 freeswitch是一款简单好用的VOIP开源软交换平台. 在之前的文章,我们介绍过distributor模块实现多线路分发的配置方法,但是当线路发生故障时,distributor并不会自动跳 ...

  5. java项目实践-jsp-filter-监听器-day19

    目录 1. jsp 2. 过滤器 3. listener 监听器 1. jsp servle逻辑处理方便 html页面表现麻烦 jsp 页面表现方便 但是逻辑处理麻烦 JSP 是一种页面技术 JSP本 ...

  6. text, data and bss: Code and Data Size Explained

    [来源]

  7. shell-命令行位置参数-$n

  8. [转帖]elasticsearch 8.0 linux安装部署

    1. 下载安装包 https://www.elastic.co/cn/downloads/elasticsearch 选择下载linux版本,elasticsearch-8.0.0-linux-x86 ...

  9. [转帖]Redis核心技术与实战

    https://www.cnblogs.com/strick/p/14851429.html 最近在读一篇关于Redis的专栏,叫做<Redis核心技术与实战>,作者在Redis方面研究颇 ...

  10. [转帖]关于gdb相关的几个工具的说明

    https://phpor.net/blog/post/846 使用rpm命名查看gdb的rpm包,主要由下面几个程序:/usr/bin/gcore/usr/bin/gdb/usr/bin/gdbse ...