私たちの製品は Linux 2.6.32 を実行しており、定期的に実行されるユーザー空間プロセスがいくつかあります - 「キープアライブ」のようなプロセスです。これらのプロセスには厳しい要件はありません。数秒に 1 回実行し、ウォッチドッグを更新するだけで済みます。
これらのプロセスに最大優先度の RR または FIFO のスケジューリング クラスを割り当てましたが、多くの誤検出が見られます。数秒間 CPU を取得していないようです。LinuxはRT OSではありませんが、それでも非常に優れたパフォーマンスを発揮できることを知っているため、非常に奇妙だと思います(数ミリ秒のオーダーについて話している人を見かけます)-そして、プロセスを5回に1回実行することさえできません秒
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(¤t_time);
fprintf(fl,"\n (%s) - had a gap of %d [msec] instead of 1000\n", ctime(¤t_time), spent_time);
}
fclose(fl);
gettimeofday(&start, 0);
}
return 0;
}
私はこのプロセスをいくつかのマシンで一晩実行しました - 私たちの製品を実行していないマシン (単純な Linux) を含む - プロセス DID が優先されることを確認したにもかかわらず、まだ数秒のギャップが見られました - そして私は理解できません理由 - 技術的には、このプロセスは他の実行中のプロセスを先取りする必要があります。
いくつかのメモ:
- これらのプロセスは主に仮想マシンで実行したため、ハイパーバイザーからの介入が発生する可能性があります。しかし、過去に物理マシンでもそのような動作を見てきました。
- プロセスを RT にすると、結果は大幅に改善されましたが、問題が完全に防止されたわけではありません。
- Linux の移行とウォッチドッグ プロセスを除いて、マシン上で実行されている他の RT プロセスはありません (プロセスが枯渇する可能性はないと思います)。
私に何ができる?ここで非常に基本的な何かが欠けているように感じます。
ありがとう!