0

我正在尝试编写一个使用实时调度策略 SCHED_FIFO 调度不同进程的进程管理器。我想要做的是设置进程的优先级并让它们根据优先级执行。

我有暂停的测试流程,并等待流程管理器恢复,以便他们执行任务。

以下是测试过程的部分代码:

while(1) {
  kill(myPid, SIGTSTP); // pause process until resumed by scheduler
  printf("Process %s with PID %d and priority %d\n",
  argv[0], myPid, param.sched_priority);
  printf("Process %s processing...\n", argv[0]);
  k = 0;

  for (i = 0; i < 10000; i++) // do random task
  {
     for (j = 0; j < 10000; j++)
     {
        k++;
     }
  }
  printf("Process %s done.  Going to sleep.\n", argv[0]);
  sched_yield(); // yield the processor
}

以下是流程管理器的示例代码:

pid_t child[3]; // holds child processes
while(1)
{

    for (i = 0; i < num_child; i++)
    {
       kill(child[i], SIGCONT); // resume process
       child_param.sched_priority = BASE_CHILD_PRIORITY + i * 10; // set priority
       sched_setscheduler(child[i], SCHED_FIFO, &child_param); // set policy
    }

}

尽管我能够获得首先运行的最高优先级,但这些进程在让处理器之前并没有完全完成它们的任务。我的问题的输出如下所示。

Process 1 with PID 5975 and priority 79
Process 1 processing...
Process 2 with PID 5974 and priority 69
Process 3 with PID 5973 and priority 59
Process 2 processing...
Process 3 processing...
Process 1 done.  Going to sleep.
Process 2 done.  Going to sleep.
Process 3 done.  Going to sleep.

为什么具有 SCHED_FIFO 策略的进程没有在下一个进程开始之前完成它们的全部任务?

4

1 回答 1

1

从手册页sched_setscheduler()

对于根据该政策安排的流程SCHED_FIFO,适用以下规则:

  1. 被另一个更高优先级进程抢占的SCHED_FIFO进程将保持在其优先级列表的头部,并在所有更高优先级进程再次被阻塞时恢复执行。

  2. 当一个SCHED_FIFO进程变为可运行时,它将被插入到列表的末尾以获取其优先级。

  3. 调用sched_setscheduler()orsched_setparam()将把 SCHED_FIFOpid 标识的进程放在列表的开头,如果它是可运行的。因此,如果它具有相同的优先级,它可能会抢占当前正在运行的进程。(POSIX.1-2001 指定进程应该到列表的末尾。)

  4. 进程调用sched_yield()将被放在列表的末尾。

Rule1Rule3间接暗示SCHED_FIFO只有在没有安排另一个更高优先级的进程时才保证 FIFO 行为。


再往下看手册页

根据实时策略之一调度的进程的sched_priority值在 1(低)到 99(高)的范围内。

代码段中的以下代码行

child_param.sched_priority = BASE_CHILD_PRIORITY + i * 10;

为后面的进程设置更高的优先级。因此,它们倾向于抢占较早的进程。

注意:POSIX.1-2001 要求实现仅支持实时策略的至少 32 个不同的优先级,而某些系统仅提供此最小值。便携式程序应该使用sched_get_priority_min()sched_get_priority_max()找到支持特定策略的优先级范围。

于 2013-08-31T04:23:54.483 回答