2

同時に2つから4つのスレッドを持つマルチスレッドプログラムを作成しました。スレッドの 1 つはタイム クリティカルなスレッドで、500 ミリ秒ごとに呼び出されます。10 ミリ秒を超える遅延は許可されません。しかし、他のスレッドの負荷が大きくなると、約 2 ミリ秒の遅延が発生することがわかりました。(タイムスタンプを印刷して表示) だから、長時間実行した後、タイムスタンプをチェックすることを除いて、10 ミリ秒以上遅延するのではないかと心配し、ループ間隔を調整して、時間が 10 ミリ秒以上遅延しないようにします。 、安全にする方法はありますか?

ありがとう。

4

5 に答える 5

4

リアルタイムJavaが必要なようです

于 2012-04-17T06:45:21.207 に答える
2

タイミングが重要な場合は、そのスレッド専用のコアでビジー待機を使用します。これにより、ほとんどの場合、<< 10 マイクロ秒のジッターが発生する可能性があります。これは少し極端であり、論理スレッドが他の目的で使用されなくなります。

これは私が使用するライブラリです。これを使用して、論理スレッドまたはコア全体を予約できます。https://github.com/peter-lawrey/Java-Thread-Affinity

Linux の grub.conf で isolcpus= を使用すると、論理スレッドまたはコアが他の目的で使用されないようにすることができます (100 Hz タイマーと電源管理は比較的小さく、遅延が 2 us 未満です)。

于 2012-04-17T06:59:41.553 に答える
1

スレッドの優先度を設定できます。

myCriticalThread.setPriority(Thread.MAX_PRIORITY);
otherThread.setPriority(Thread.NORM_PRIORITY); // the default
yetAnotherThread.setPriority(Thread.MIN_PRIORITY);

ただし、実際には何も保証されません。

于 2012-04-17T06:41:17.347 に答える
0

タイムアウトに忍び寄る:

waitFor(int timeout)
{
  dateTime wallTimeEnd;
  wallTimeEnd=now()+(msToDateTime(timeout));
  int interval=timeout/2;
  while(true){
    if(interval>10){
      sleep(interval);
      interval=dateTimeToMs(wallTimeEnd-now()) / 2;
    } 
      else
      {
        do{
          sleep(0);
          interval=dateTimeToMs(wallTimeEnd-now());
        }while(interval>0);
  }
}

これは5-10msの間コアを浪費するだけです

于 2012-04-17T11:46:49.087 に答える
0

OS が他のプロセスを優先することを決定する可能性があるため、スレッドが遅延しないという保証はありません (変更された OS を含む完全なリアルタイム システムをセットアップする努力をしない限り)。そうは言っても、基本的なタスクについては、次のようにScheduledExecutorServiceを使用する必要があります。

class A {
  private final ScheduledExecutorService exe = Executors.newScheduledThreadPool(1);

  public void startCriticalAction(Runnable command) {
    this.exe.scheduleAtFixedRate(command, 100, 100, TimeUnit.MILLISECONDS);
  }

  public void shutdown() {
    this.exe.shutdown();
  }
}

Executor サービスは、100 ミリ秒ごとにタスクを実行するために最善を尽くします。多くのことがうまくいかない可能性があるため、この機能を自分で開発しないでください。

于 2012-04-17T06:47:36.133 に答える