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

5 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;
}
Run Code Online (Sandbox Code Playgroud)

我得到的输出总是:

In parent
In Child
Run Code Online (Sandbox Code Playgroud)

我在这里想错了吗?

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

Jam*_*ess 8

从我可以看出,sched_child_runs_first功能的实现位置在task_fork_fair函数中,您可以在此处看到源.

该函数的关键部分如下所示:

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);
}
Run Code Online (Sandbox Code Playgroud)

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

请注意,首先使用与当前任务相同的值初始化新实体的vruntime.这是显著,因为entity_before呼叫正在检查是否vruntimeCURR小于vruntime本质.

这样条件会成功的唯一途径是,如果place_entity调用设置vruntime本身更大的东西.那么让我们来看看它的来源.关键位是:

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);
Run Code Online (Sandbox Code Playgroud)

因此,假设START_DEBIT设置了该功能(似乎就是这种情况),那么vruntime将被设置为运行队列的min_vruntime加上sched_vslice调用返回的任何内容.如果这大于当前的vruntime,那么我们就设置了 - 如果没有,我们将留下我们的初始vruntime值,条件将不会成功.

我不太清楚Linux调度是否可以肯定地说,但我猜测min_vruntime plus sched_vslice在大多数时候都不够大.

我说大部分时间是因为,当我测试时,我能够让孩子进程至少在某些时候首先运行.所以sched_child_runs_first参数确实有所作为 - 这不是任何保证.

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