/ proc / sys / kernel / sched_child_runs_first有效吗?

时间:2013-06-30 14:09:58

标签: c linux linux-kernel

我了解到在/proc/sys/kernel/sched_child_runs_first中设置非零值会强制子进程在父进程之前运行。但是,我认为它似乎不起作用。这是我的代码:

#include <stdio.h>
#include <sys/types.h>

int main(int argc, char **argv)
{
  pid_t child_pid;

  switch(child_pid = fork())
    {
    case 0:
      printf("In Child\n");
      exit(0);

    case -1:
      printf("Could not fork()\n");

    default:
      printf("In parent\n");

    }
  return 0;
}

我得到的输出总是:

In parent
In Child

我在这里期待有什么问题吗?

PS:我只是在试验它是否有效,所以请不要建议其他同步机制或为什么这是一个坏主意等等。

1 个答案:

答案 0 :(得分:8)

据我所知,实现sched_child_runs_first功能的地方位于task_fork_fair功能,您可以看到here的来源。

该功能的关键部分如下所示:

if (curr)
        se->vruntime = curr->vruntime;
place_entity(cfs_rq, se, 1);

if (sysctl_sched_child_runs_first && curr && entity_before(curr, se)) {
        swap(curr->vruntime, se->vruntime);
        resched_task(rq->curr);
}

se 是新的调度实体, curr 是当前任务的调度实体。

请注意,新实体的 vruntime 首先使用与当前任务相同的值进行初始化。这很重要,因为entity_before调用正在检查 curr vruntime 是否小于 se的 vruntime

因此条件成功的唯一方法是place_entity调用将 se vruntime 设置为更大的值。那么让我们看一下source。关键位是:

u64 vruntime = cfs_rq->min_vruntime;

if (initial && sched_feat(START_DEBIT))
        vruntime += sched_vslice(cfs_rq, se);

se->vruntime = max_vruntime(se->vruntime, vruntime);

假设设置了START_DEBIT功能(seems to be the case),则 vruntime 将设置为运行队列的 min_vruntime 加上任何内容sched_vslice调用返回。如果这大于当前 vruntime 那么我们就设置了 - 如果没有,我们将留下我们的初始 vruntime 值,条件将不会成功。

我不太清楚Linux调度,但我猜测 min_vruntime 加上sched_vslice大部分时间都不够大。

我说大部分时间是因为,当我测试时,我能够让孩子进程至少在某些时候首先运行。所以sched_child_runs_first参数确实可能会产生影响 - 它不是任何保证。

另一种可能性是它是代码中的一个错误,它们应该在计算初始值时以当前任务的 vruntime 而不是运行队列的 min_vruntime 开始在place_entity函数中。这将保证条件成功。但我怀疑有理由按照我们不理解的方式做事。