线程的调度

线程的执行总是趋向于CPU受限或IO受限

一些线程需要花费一定的时间使用CPU进行计算,而另外一些线程则会花费一些时间等待相对较慢的I/O操作的完成

一个用于计算16位整数的14次方根的线程属于前者,而一个等待人类用户通过敲击键盘提供输入数据的线程则属于后者

调度器会依据它对线程的趋向性的猜测把它们分类,并让I/O受限的线程具有更高的动态优先级以优先使用CPU。因为IO操作往往会花费更长时间,应该让它们尽早开始

线程的优先级调整

线程的动态优先级是可以被调度器实时调整的,而与之相对应的线程的静态优先级则只能由应用程序指定

如果应用程序没有显式指定一个线程的静态优先级,那么它将被设定为0

调度器并不会改变线程的静态优先级。线程的动态优先级就是调度器在其静态优先级的基础上调整得出的,它在线程的运行顺序上起到了关键的作用

而线程的静态优先级则决定了线程单次在CPU上运行的最长时间,也就是调度器分配给它的时间片的大小

动态优先级排序

所有等待使用CPU的线程会按照动态优先级从高到低的顺序排列,并依序放到与该CPU对应的运行队列中

因此,下一个运行的线程总是动态优先级最高的那一个

实际上,每一个CPU的运行队列中都包含两个优先级阵列

  • 用于存放正在等待运行的线程,称之为激活的优先级阵列
  • 用于存放已经运行过但还未完成的线程,称之为过期的优先级阵列

优先级阵列是一个由若干个链表组成的数组。一个链表只会包含具有相同优先级的线程,而一个线程也只会放到与其优先级相对应的那个链表中

当一个线程放入某个优先级阵列时,实际上就放到了与其优先级相对应的那个链表的末尾处

在这里插入图片描述

优先队列的运行

下一个运行的线程总是会从激活的优先级阵列中选出

如果调度器发现某个线程已经占用了CPU很长时间(该时间只会小于或等于给予线程的时间片)

并且激活的优先级阵列中还有优先级与它相同的线程在等待运行,那么调度器就会让那个等待的线程在CPU上运行,而被换下的线程会排入过期的优先级

当激活的优先级阵列中没有待运行的线程时,调度器会把这两个优先级阵列的身份互换,即之前的激活优先级阵列成为新的过期的优先级阵列,而之前的过期的优先级阵列则会成为新的激活的优先级阵列

如此一来,之前被放入过期的优先级阵列的线程就又有机会运行了

线程的状态

线程会因等待某个事件或条件的发生而加入到对应的等待队列中,并随即进入睡眠状态

当事件发生或条件满足时,内核会通知对应的等待队列中的所有线程,这些线程会因此而被唤醒并从等待队列转移至适当的运行队列中

调度器往往会稍稍调高唤醒的线程的动态优先级

线程与CPU

如果当前计算机上有多个CPU,那么平衡它们之间的负载也将会调度器的职责之一

调度器会尽量使一个线程在一个特定的CPU上运行。这样就可以维持高速缓存的高命中率以及高效使用就近的内存

有时候,一个CPU需要运行太多线程以至于造成了多CPU之间负载的不平衡。也就是说,一些CPU过于忙碌,另一些被闲置

在这种情况下,调度器会把一些原来在较忙碌CPU上运行的线程迁移至其他较空闲的CPU上运行

由于内核会为每个CPU建立一个运行队列,所以线程的这种迁移并不困难

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值