/proc/sys/kernel/sched_child_runs_first 工作吗?

2023-12-05

我了解到设置一个非零值/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函数,您可以看到其来源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调用正在检查是否vruntime of curr小于vruntime of se.

因此,该条件成功的唯一方法是place_entity调用设置vruntime of se到更大的事情。那么让我们看看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功能已设置(其中似乎是这样),那么vruntime将被设置为运行队列的分钟虚拟运行时间加上无论什么sched_vslice呼叫返回。如果这个值大于当前值vruntime那么我们就准备好了——如果没有,我们将只剩下我们最初的vruntime值和条件不会成功。

我不太了解 Linux 调度,无法肯定地说,但我猜分钟虚拟运行时间 plus sched_vslice大多数时候只是不够大。

我说大多数时候是因为,当我测试时,我至少在某些时候能够让子进程先运行。所以有可能sched_child_runs_first参数确实有影响——它只是不能保证任何事情。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

/proc/sys/kernel/sched_child_runs_first 工作吗? 的相关文章

随机推荐