• 【Linux内核】CPU和线程


     

    首先明确一个概念,Linux系统中甚至没有真正的线程。不过,可以认为Linux是系统的线程是内核线程,所有调度是基于线程的。

    1、线程分类

    一个进程由于其运行空间的不同, 从而有内核线程用户进程的区分,进程和线程都被维护为一个task_struct结构,线程和进程被同等对待来进行调度

    • 内核线程运行在内核空间, 之所以称之为线程是因为它没有虚拟地址空间, 只能访问内核的代码和数据, 而用户进程则运行在用户空间, 但是可以通过中断, 系统调用等方式从用户态陷入内核态
    • 用户进程运行在用户空间上, 而一些通过共享资源实现的一组进程我们称之为线程组, Linux下内核其实本质上没有线程的概念, Linux下线程其实上是与其他进程共享某些资源的进程而已。但是我们习惯上还是称他们为线程或者轻量级进程

    Linux将线程区分为3类:

    (1)实时先入先出。

    (2)实时轮转。

    (3)分时。

    实时先入先出有最高的优先级,不会被其他线程抢占,除非是另外一个刚刚准备好的且优先级更高的实时先入先出线程。

    实时轮转线程与实时先入先出类似,不过有一个轮转体系,即分配一个时间片,时间到了就可以被抢占。时间片消耗完就进入实时轮转线程列表的末尾。其实,这两种都不是真的实时,因为执行的最后期限无法确定,只是比分时线程有更高的优先级。

    实时线程的优先级从0-99,0是实时线程的最高优先级,99是实时线程的最低优先级。

    传统的非实时线程,优先级从100-139。Linux系统根据非实时线程的优先级分配时间量。

    2、调度队列和多CPU负载均衡

    每个CPU有自己的调度队列,包括两个数组:活动的和过期失效的。每个数组包括了140个链表头,对应140个优先级的链表。

    调度器从正在活动数组中选择一个优先级最高的任务,如果时间片耗尽失效,就加入到过期失效数组中。如果进程在时间片内被阻塞,那么在时间片失效之前,等待的事件发生就可以继续运行,放回到正在活动的数组中。如果活动数组没有任务了,调度器交换指针,使得活动数组和失效数组调换。

    不同的优先级被赋予不同的时间片长度,优先级越高的进程,时间片越长。

    如果每个CPU调度队列的大小很不均衡,就会触发内核的load_balance函数。这个函数会把某个CPU处理器上过多的进程移到runqueue元素相对少的CPU处理器上。

    3、线程优先级

    Linux采用静态优先级动态优先级结合的方式。Linux采用了奖惩机制,目的在于奖励互动进程以及惩罚占用CPU的进程。一个进程初始被赋予了一个优先级,耗尽和阻塞会改变nice值,活动与过期进程转换时,动态改变进程优先级。

    另外,对于多核处理器,运行队列数据结构与某一个处理器相对应,调度器尽量进行亲和调度,即将之前在某个处理器上运行过的任务再次调入该处理器。

    调度器只考虑可以运行的任务,不可运行的任务和正在等待各种I/O操作的或内核事件的任务被放入等待队列中。每一种等待某种事件的任务组成一个等待队列。等待队列的头部包含一个指向任务链表的指针及一个自旋锁。

    4、CPU时间片

    内核在微观上,把CPU的运行时间分成许多分,然后安排给各个进程轮流运行,造成宏观上所有的进程仿佛同时在执行。双核CPU,实际上最多只能有两个进程在同时运行,大家在top、vmstat命令里看到的正在运行的进程,并不是真的在占有着CPU哈。

    所以,一些设计良好的高性能进程,比如nginx,都是实际上有几颗CPU,就配几个工作进程,道理就在这。比如你的服务器有8颗CPU,那么nginx worker应当只有8个,当你多于8个时,内核可能会放超过多个nginx worker进程到1个runqueue里,会发生什么呢?就是在这颗CPU上,会比较均匀的把时间分配给这几个nginx worker,每个worker进程运行完一个时间片后,内核需要做进程切换,把正在运行的进程上下文保存下来。假设内核分配的时间片是100ms,做进程切换的时间是5ms,那么进程性能下降还是很明显的,跟你配置的worker有关,越多下降得越厉害。

    当然,这是跟nginx的设计有关的。nginx是事件驱动的全异步进程,本身设计上就几乎不存在阻塞和中断,nginx的设计者就希望每一个nginx worker可以独占CPU的几乎全部时间片,这点就是nginx worker数量配置的依据所在。

    当然,实际的运行进程里,大部分并不是nginx这种希望独占CPU全部时间片的进程,许多进程,比如vi,它在很多时间是在等待用户输入,这时vi在等待IO中断,是不占用时间片的,内核面对多样化的进程,就需要技巧性的分配CPU时间片了。

     
     参考:
    https://www.cnblogs.com/lustar/p/7716165.html
  • 相关阅读:
    NodeJS3-1基础API----Path(路径)
    NodeJS2-6环境&调试----debug
    NodeJS2-5环境&调试----process(进程)
    NodeJS2-4环境&调试----global变量
    NodeJS2-3环境&调试----module.exports与exports的区别
    短视频秒播优化实践(二)
    短视频秒播优化实践(一)
    仿抖音上下滑动播放视频
    带着问题,再读ijkplayer源码
    上班一个月,后悔当初着急入职的选择了
  • 原文地址:https://www.cnblogs.com/wangzhongqiu/p/8902679.html
Copyright © 2020-2023  润新知