linux 优先级反转,linux进程、线程及调度算法(四)

作者: 雪山肥鱼

时间:20210523 21:08

目的:进程调度中的负载均衡

负载均衡

linux中,每个核都会跑相同的调度算法

RT

FIFO

RR

Normal

CFS(New) 红黑树,左右滚,自动奖罚

nice值奖励与惩罚(Legacy)

RT 进程(task_struct): N 个优先级最高的RT 分布到 N 个核上,每个核乐于工作

核心空的时候,pull_rt_task( ) <<<< 从其他核拿任务

核心忙的时候,push_rt_task( ) >>>> 推给其他核

RT 自动均分到多核上,及时抢到CPU,更多强调的是实时性。

普通进程(normal)

周期性负载均衡 :操作系统的时钟节拍来的时候,对比旁边CPU 的 繁忙程度,如果闲则推给旁边的CPU

IDLE时负载均衡:CPU 准备去跑idle,会看下旁边的核是不是很忙,会pull task 过来,继续干。

fork和exec时负载均衡:主动将 创建的 task_struct 推到其他比较闲的CPU

所以一个线程,可能一会在CPU 1 一会再CPU2...,但可以控制线程在哪个核上

CPU task affinity 亲和性

//np: not posix 非posix api

int pthread_attr_setaffinity_np(pthread_attr_t*, size_t, const cpu_set_t *);

int pthread_attr_getaffinity_np(pthread_attr_t*, size_t, cpu_set_t*);

int sched_setaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask);

int sched_getaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask);

设置线程向哪个CPU 亲和,设置cpu_set_t 掩码: 0x6(110),指向在 1 2 两个核上跑。设置为0x4:(100), 则指在2号CPU上跑。

taskset -a -p 01 29991

//命令设置进程在哪个核上跑。如果2个死循环线程跑在两个CPU上

//则从200% 降低到100%。因为所有线程都跑在一个核上啦

IRQ affinity 中断的负载均衡

分配IRQ到某个CPU

220aba97466e

多队列网卡.png

网卡有4个队列,每个队列的收发中断,分别设置成 1 2 4 8,则均分到4个核上,这就是中断的负载均衡。

如果一张网卡只有一个队列,但是有8个核,中断发给了第0个核,当CPU0 收到中断IRQ后,如果在cpu0 中又调了一个 soft IRQ,这个中断也会运行在cpu0,中断调度的软中断也会运行在同一cpu上的。所以对于cpu0来说,中断和软中断的负载都很重,TCP/IP处理都丢到软中断里去了。cpu0 忙的要死,旁边7个核看热闹,包的吞吐率肯定上不来。

linux提交的RPS补丁,将包处理负载均衡到多个cpu。

//软中断负载均衡到1-15个核上去,4个f 则 0-15 负载均衡。

//fffe 将自己的软中断派发到其他cpu上,所以的cpu 核参与到 包的吞吐

echo fffe > /sys/class/net/eth1/queues/rx-0/rps_cpus fffe

cgroups 进程的分群

示例:2个用户 在一台服务器上工作,比如编译,A用户创了1000个线程, B用户创建了32个线程,如果nice值都是0,则A线程占CPU的比例远远大于B线程占CPU的比例。

所以再引出一层: 分组。群与群之间先做完全公平调度。

群与群之间进行FC调度,群内部再进行CFS调度

cgourp 有一系列的操作,后续遇到再好好总结吧。

Hard realtime 可预期性

硬实时

在一定时间内必须有响应。比如导弹发射,从按按钮到发射,1ms。超过1ms 后果时灾难性的

软实时

可以超过截止期限,就算超过也非灾难性。linux是软实时的。

硬实时与软实时是按照需求来的。

kernal 越来越支持抢占

220aba97466e

linux 抢占区间.png

可抢占区域逐步增加,linux内核也会被抢占

当linux 被打上硬实时补丁,就会到第四种情况,只存在点状不可调度区域。

linux 为什么不是硬实时

从linux不可调度实际,以及四类区间进行分析 。

220aba97466e

四个区间.png

linux大部分运行在四个区间中.

中断区间

被中断是 RT进程被唤醒,拒绝调度

软中断区间

软中断过程中,RT进程被唤醒,也拒绝调度

进程

3.1 spin_lock(线程拿了把锁)

整个核的调度都被关啦,RT 当然拒绝调度

3.2 可调度的上下文

只有此时可以调度。

只有当1、2、3类区间都结束,才会开启抢断,RT进程运行。

220aba97466e

抢占时机.png

T0 时刻 系统调用陷入内核

T1 拿到自旋锁

T2 软中断

T3 时刻 RT 进程被唤醒(RR/FIFO)

T4 时刻 再被中断

T5 出中断,但依旧不会响应 RT进程

出了临界区,RT 才被响应.

从T3 到T6 的延迟都是不可预知的,所以 linux 不是硬实时的,而是软实时的。

当linux 打上RT补丁后

spinlock 迁移为可调度的mutex, 同时报了raw_spin_lock_t

spinlock 编程了可以睡的mutex,mutex是不会锁调度器的。

对于mutex,t1 拿到了mutex, t2就睡,直到t1 放mutex, t2才醒,拿不到就睡,放了就醒

spinlock:有两个cpu,cpu0 拿到了spinlock,cpu0的调度器被关掉,cpu1要想拿到spinlock 就要原地打转。spinlock 发生在两个核之间。

实现优先级继承协议(优先级反转等)

非RT补丁,已经进到linux内核中了。

反转

Low level 进程抢到锁,H level 在等,但是期间一直有 M level 进程在折腾Low level 进程,一直在抢low level的锁,H 一直抢不到。所以看上去像 M level 的优先级 高于 H level。H level 很久才拿到这个锁

继承

Low level 优先级低,过了一段时间,H level 要拿L 的锁,linux会做一件事,临时把Low leve 优先级提高和 H level 一样,这样 M level 就不会折腾这个Low level 的 进程。

中断线程化

中断丢到线程里做,那么就就可以被其他线程强调

软中断线程化

同理 丢到线程里做,也会被抢占。

其实就是把区间1,2,3 都变成了四类区间。所以linux 变成了硬实时。(中断服务也变成及其的短)

RT补丁就是第4个完全抢占

No forced Preemption(Server)

Voluntary kernal preemption(Desktop)

Preemptible Kernal (Low latency Desktop)

Complete Preemption(RealTime)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值