5

ゼロ以外の値を設定する/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: 動作するかどうかを実験しているだけなので、他の同期メカニズムや、なぜこれが悪い考えなのかなどを示唆することは控えてください。

4

1 に答える 1

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

seは新しいスケジューリング エンティティで、currは現在のタスクのスケジューリング エンティティです。

新しいエンティティのvruntimeは、最初に現在のタスクと同じ値で初期化されることに注意してください。呼び出しはcurrのvruntimeseのvruntimeより小さいentity_beforeかどうかをチェックしているため、これは重要です。

したがって、その条件が成功する唯一の方法は、呼び出しがseのvruntimeをより大きな値にplace_entity設定する場合です。それでは、そのソースを見てみましょう。キービットは次のとおりです。

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ます。これは、何かを保証するものではありません。

もう 1 つの可能性は、コードのバグであり、関数で初期値を計算するときに、実行キューのmin_vruntimeではなく、現在のタスクのvruntimeで開始する必要があることです。これにより、条件が成功することが保証されます。しかし、私が理解していない理由があると思います。place_entity

于 2013-06-30T18:01:56.230 に答える