详解Linux内核进程调度函数schedule()的触发和执行时机

 更新时间:2018年01月24日 11:23:07   作者:Q_AN1314  
这篇文章主要介绍了详解Linux内核进程调度函数schedule()的触发和执行时机,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

内核的调度操作分为触发和执行两个部分,触发时仅仅设置一下当前进程的TIF_NEED_RESCHED标志,执行的时候则是通过schedule()函数来完成进程的选择和切换。当前进程的thread_info->flags中TIF_NEED_RESCHED位表示需要调用schedule()函数进行调度。内核在两种情况下会设置该标志,一个是在时钟中断进行周期性的检查时,另一个是在被唤醒进程的优先级比正在运行的进程的优先级高时。

周期性地更新当前任务的状态时:

定时中断处理函数中会调用schedule_tick()用于处理关于调度的周期性检查和处理,其调用路径是和时钟处理有关的tick_periodic()->update_process_times()->scheduler_tick()或者tick_sched_handle()->update_process_times()->scheduler_tick(),主要用于更新就绪队列的时钟、CPU负载和当前任务的运行时间统计等,如下所示:

//linux-3.13/kernel/sched/core.c
void scheduler_tick(void)
{
  int cpu = smp_processor_id();         //获取当前cpu编号
  struct rq *rq = cpu_rq(cpu);         //取得对应cpu的rq(就绪队列)
  struct task_struct *curr = rq->curr;     //获取当前运行的任务

  sched_clock_tick();

  raw_spin_lock(&rq->lock);
  update_rq_clock(rq);             //更新队列时钟
  curr->sched_class->task_tick(rq, curr, 0);  //调用当前任务的调度类对应的函数
  update_cpu_load_active(rq);          //更新本处理器的负载
  raw_spin_unlock(&rq->lock);

  perf_event_task_tick();

#ifdef CONFIG_SMP
  rq->idle_balance = idle_cpu(cpu);
  trigger_load_balance(rq, cpu);        //必要时进行负载均衡
#endif
  rq_last_tick_reset(rq);
}

其中curr->sched_class->task_tick(rq, curr, 0);这行代码调用了当前任务的调度类的task_tick()函数,这个函数根据具体情况决定是否需要对当前任务设置TIF_NEED_RESCHED标志,如果需要则最终调用set_tsk_need_resched()设置该标志。需要注意的是,此处仅仅是设置标志而没有执行schedule()函数,在各种系统调用、中断的返回代码最后,才会根据这个标志来决定是否执行schedule()函数。

睡眠的任务被唤醒时:

当睡眠任务所等待的事件到达时,内核(例如驱动程序的中断处理函数)将会调用wake_up()唤醒相关的任务,并最终调用try_to_wake_up()。它完成三件事:将任务重新添加到就绪队列,将运行标志设置为TASK_RUNNING,如果被唤醒的任务可以抢占当前运行任务则设置当前任务的TIF_NEED_RESCHED标志。

设置了TIF_NEED_RESCHED标志之后,真正调用执行schedule()函数的时机只有两种,第一种是系统调用或者中断返回时,根据TIF_NEED_RESCHED标志决定是否调用schedule()函数(从效率方面考虑,趁着还在内核态把该处理的事情处理完毕);第二种情况是当前任务因为原因需要睡眠,进程睡眠后立即调用schedule()函数,在内核中这种情况也比较多,比如磁盘、网卡等设备驱动程序中。

参考文献:《Linux技术内幕》

PS:刚开始学习Linux内核的时候很容易被各种结构体各种概念充斥脑海,一团乱麻。这时候需要把它们各自负责的功能以及之间相互的配合理清楚,推荐这本书。看完《Linux内核设计与实现》后可以相互比照,效果不错。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Linux推荐使用Xfce桌面环境的8个原因

    Linux推荐使用Xfce桌面环境的8个原因

    今天小编就为大家分享一篇关于Linux推荐使用Xfce桌面环境的8个原因,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-09-09
  • apache性能测试工具ab使用详解

    apache性能测试工具ab使用详解

    这篇文章主要介绍了apache性能测试工具ab使用详解,需要的朋友可以参考下
    2015-01-01
  • Linux中使用NTP保持精确时间的方法详解

    Linux中使用NTP保持精确时间的方法详解

    Linux系统下,一般使用ntp服务来同步不同机器的时间,NTP 是网络时间协议(Network Time Protocol)的简称,下面这篇文章主要给大家介绍了关于Linux中使用NTP保持精确的时间的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。
    2018-03-03
  • 详解Linux多线程使用信号量同步

    详解Linux多线程使用信号量同步

    本篇文章主要是介绍了Linux多线程使用信号量同步,详细讲诉了信号量的接口和使用,有需要的朋友可以了解一下。
    2016-10-10
  • linux(centos)下SVN服务器如何搭建

    linux(centos)下SVN服务器如何搭建

    linux(centos)下SVN服务器如何搭建?说到SVN服务器,想必大家都知道,可以是在LINUX下如何搭建SVN服务器呢?那么今天给大家分享一下linux(centos)搭建SVN服务器的思路!
    2015-09-09
  • CentOS虚拟机克隆后无法上网(网卡信息不一致)问题的解决方法

    CentOS虚拟机克隆后无法上网(网卡信息不一致)问题的解决方法

    这篇文章主要为大家详细介绍了CentOS虚拟机克隆后无法上网,即网卡信息不一致问题的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-04-04
  • Linux下使用ip netns命令进行网口的隔离和配置ip地址

    Linux下使用ip netns命令进行网口的隔离和配置ip地址

    这篇文章主要介绍了Linux下使用ip netns命令进行网口的隔离和配置ip地址,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • 在服务器上启用HTTP公钥固定扩展的教程

    在服务器上启用HTTP公钥固定扩展的教程

    这篇文章主要介绍了在服务器上启用HTTP公钥固定扩展的教程,示例包括对Apache和NGINX以及Lighttpd服务器的演示,需要的朋友可以参考下
    2015-06-06
  • ubuntu开启SSH服务远程登录操作的实现

    ubuntu开启SSH服务远程登录操作的实现

    这篇文章主要介绍了ubuntu开启SSH服务远程登录操作的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • CentOS 7更新时出现:Multilib version problems问题的解决方法

    CentOS 7更新时出现:Multilib version problems问题的解决方法

    这篇文章主要给大家介绍了关于CentOS 7系统更新时出现:Multilib version problems问题的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-11-11

最新评论