0

我们的产品正在运行 linux 2.6.32,并且我们有一些定期运行的用户空间进程 - “保持活动 - 类似”进程。我们对这些进程没有严格的要求——它们只需要在几秒钟内运行一次并刷新一些看门狗。

我们为这些进程提供了一个具有最大优先级的 RR 或 FIFO 调度类,然而,我们看到了许多误报——似乎它们在几秒钟内都没有获得 CPU。我觉得这很奇怪,因为我知道 Linux 虽然不是 RT 操作系统,但仍然可以产生非常好的性能(我看到人们在谈论几毫秒的订单)——我什至无法让该进程在 5 次中运行一次秒。

Linux RT 调度程序的逻辑似乎非常直接和简单,所以我怀疑这些进程被其他东西阻塞了——I/O 争用、中断或内核线程耗时太长——但现在我不太确定:我写了一个模拟这样一个过程的非常基本的程序 - 它每 1 秒唤醒一次,并测量自上次完成运行以来所花费的时间。据我了解,时间测量不包括任何 I/O 上的阻塞,因此此过程打印的结果反映了调度程序的行为:

#include <sched.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/param.h>
#include <time.h>

#define MICROSECONDSINASEC 1000000
#define MILLISECONDSINASEC 1000

int main()
{
    struct sched_param schedParam;
    struct timeval now, start;
    int spent_time = 0;
    time_t current_time;

    schedParam.sched_priority = sched_get_priority_max(SCHED_RR);
    int retVal = sched_setscheduler(0, SCHED_RR, &schedParam);
    if (retVal != 0)
    {
        printf("failed setting RT sched");
        return 0;
    }

    gettimeofday(&start, 0);
    start.tv_sec -= 1;
    start.tv_usec += MICROSECONDSINASEC;

    while(1)
    {
        sleep(1);
        gettimeofday(&now, 0);
        now.tv_sec -= 1;
        now.tv_usec += MICROSECONDSINASEC;
        spent_time = MILLISECONDSINASEC * (now.tv_sec - start.tv_sec) + ((now.tv_usec -       start.tv_usec) / MILLISECONDSINASEC);

        FILE *fl = fopen("output_log.txt", "aw");

        if (spent_time > 1100)
        {
            time(&current_time);
            fprintf(fl,"\n (%s) - had a gap of %d [msec] instead of 1000\n",                       ctime(&current_time), spent_time);
        }

        fclose(fl);
        gettimeofday(&start, 0);
    }

    return 0;
}

我在一夜之间在几台机器上运行了这个过程——包括那些不运行我们的产品的机器(只是普通的 Linux),我仍然看到了几秒钟的间隙——即使我确保进程 DID 获得了优先级——我不知道为什么 - 从技术上讲,这个进程应该抢占任何其他正在运行的进程,那么它怎么能等待这么长时间才能运行呢?

几点注意事项:

  1. 我主要在虚拟机上运行这些进程 - 所以可能会有来自管理程序的干预。但在过去,我也曾在物理机器上看到过这种行为。
  2. 制作过程 RT 确实极大地改善了结果,但并没有完全避免这个问题。
  3. 除了 Linux 迁移和看门狗进程(我不相信这会导致我的进程饥饿)之外,机器上没有运行其他 RT 进程。

我能做些什么?我觉得我在这里遗漏了一些非常基本的东西。

谢谢!

4

0 回答 0