c - 了解 Linux 内核调度程序

标签 c linux linux-kernel scheduler

我正在研究 Linux 内核并试图弄清楚 Round Robin 调度算法的工作原理。在 kernel\sched_rt.c 文件中,有一个名为 task_tick_rt 的方法定义如下:

static void task_tick_rt(struct rq *rq, struct task_struct *p, int queued)
{
    update_curr_rt(rq);

    watchdog(rq, p);

    /*
     * RR tasks need a special form of timeslice management.
     * FIFO tasks have no timeslices.
     */
    if (p->policy != SCHED_RR)
            return;

    if (--p->rt.time_slice)
            return;

    p->rt.time_slice = DEF_TIMESLICE;

    /*
     * Requeue to the end of queue if we are not the only element
     * on the queue:
     */
    if (p->rt.run_list.prev != p->rt.run_list.next) {
            requeue_task_rt(rq, p, 0);
            set_tsk_need_resched(p);
    }

我不明白的(除了有一个无用的 queued 参数)是代码试图通过 if (--p->rt.time_slice ) 检查。我不明白为什么任务列表指针 p 会减 1,换句话说,为什么方法检查的是 previous task 而不是当前任务?对此的任何澄清表示赞赏。

最佳答案

查看 c 运算符优先级 http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Operator_precedence

-> 运算符的优先级高于前缀 ++,因此可以编写此特定条件:

if (--(p->rt.time_slice))

换句话说,递减的是时间片,而不是指针。


queued 参数在这里可能看起来毫无用处,但它存在是有原因的。特别注意从哪里调用 task_tick_rt()。它唯一的引用是当它被分配给 struct sched_classrt_sched_class 实例中的 .task_tick 函数指针时: http://lxr.free-electrons.com/source/kernel/sched/rt.c#L1991

所以我们看到每个调度算法都有自己的 struct sched_class 函数 vector ,内核将调用它来调度服务。如果我们看看其他算法,我们会看到 CFS(完全公平调度)算法也有它自己的 struct sched_class 实例,名为 fair_sched_class: http://lxr.free-electrons.com/source/kernel/sched/fair.c#L6179

CFS案例中的.task_tick成员指向task_tick_fair(): http://lxr.free-electrons.com/source/kernel/sched/fair.c#L5785

请注意 task_tick_fair() 是否 使用 queued 参数。因此,当调用 .task_tick 成员时(herehere),queued 参数将传入 0 或 1。因此,尽管 task_tick_rt() 不使用它,但 queued 参数必须仍然是它们的参数,因此 struct sched_class 函数 vector 中的函数指针类型全部匹配。

简而言之,struct sched_class 函数 vector 指定了调度算法与内核其余部分之间的接口(interface)。 queued 参数是应该给定的算法选择使用它,但在 Round Robin 的情况下,它被简单地忽略。

关于c - 了解 Linux 内核调度程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19327213/

相关文章:

linux - 如何将管道的grep结果写入文件

linux - 将闪电节点更新到最新版本

linux-kernel - 为什么有些代码使用 NULL 作为 irq_handler 的参数调用 request_threaded_irq?

c - 多个计时器到一个进程(不链接到 rt)

c - 将键盘事件保存到带有图形窗口的数组中

windows - 为什么在 windows 或 linux 下对同一个文件使用不同的 SHA-1?

linux - linux kernel 2.6 有多少个系统调用?

C 使用 isdigit 检查 optarg 是否为数字

c - 在 OpenMP 中使用任务指令的正确方法是什么

c - 如何从用户空间 C 读取内核模块 (/dev) 文件