/proc/sys/kernel/sched_child_runs_first有效吗? [英] Does /proc/sys/kernel/sched_child_runs_first work?

查看:281
本文介绍了/proc/sys/kernel/sched_child_runs_first有效吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我了解到,在/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:我只是在尝试查看它是否有效,因此请不要建议其他同步机制,或者为什么这是个坏主意,等等.

解决方案

据我所知,实现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);
}

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

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

因此条件成功的唯一方法是,如果place_entity调用将 se 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);

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

我对Linux的调度了解得不够肯定,但是我猜想 min_vruntime sched_vslice在大多数时候都不够大.

我之所以说大部分时间是因为,当我进行测试时,我能够使子进程至少在某些时候首先运行.因此,sched_child_runs_first参数有可能会有所作为-它不能保证任何事情.

另一种可能性是这是代码中的错误,在计算初始值时,它们应该从当前任务的 vruntime 开始,而不是运行队列的 min_vruntime place_entity函数中.那将保证条件将成功.但是我怀疑这样做是有原因的,我只是不明白.

I learned that setting a non-zero value in /proc/sys/kernel/sched_child_runs_first will force the child process to run before the parent. However, I don't think it seems to be working. Here is my code:

#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;
}

The output I get is always:

In parent
In Child

Am I expecting something wrong here?

PS: I am just experimenting to see if it works, so please refrain from suggesting other synchronization mechanisms or why this is a bad idea, etc.

解决方案

From what I can make out, the place where the sched_child_runs_first feature is implemented is in the task_fork_fair function, the source for which you can see here.

The key part of that function looks like this:

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 is the new scheduling entity and curr is the scheduling entity for the current task.

Note that the vruntime for the new entity is first initialised with the same value as the current task. This is significant, because the entity_before call is checking whether the vruntime of curr is less than the vruntime of se.

So the only way that condition will succeed is if the place_entity call sets the vruntime of se to something larger. So let's look at the source for that. The key bits are:

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);

So assuming the START_DEBIT feature is set (which seems to be the case), then the vruntime will be set to the run queue's min_vruntime plus whatever the sched_vslice call returns. If this is greater than the current vruntime then we're set - if not we'll be left with our initial vruntime value and the condition won't succeed.

I don't understand Linux scheduling well enough to say for sure, but I'm guessing that min_vruntime plus sched_vslice just isn't large enough most of the time.

I say most of the time because, when I was testing, I was able to get the child process to run first at least some of the time. So it's possible the sched_child_runs_first parameter does make a difference - it's just not a guarantee of anything.

The other possibility is that it's a bug in the code, and they should have started with the current task's vruntime rather than the run queue's min_vruntime when calculating the initial value in the place_entity function. That would have guaranteed the condition would succeed. But I suspect there's a reason for doing things the way they do which I just don't understand.

这篇关于/proc/sys/kernel/sched_child_runs_first有效吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆