0

ac プログラムで整数秒ごとに取得する方法があるかどうか疑問に思っています。「gettimeofday」関数を使用して現在の時刻を取得しようとしましたが、現在の秒の小数部分が領域 (0.9 より大きく 0.1 より小さいなど) に収まる場合は、現在の時刻を整数に丸めました。ただし、プログラムを実行すると、時折、数秒のミスがありました。誰かがより良い解決策を持っていますか?

ありがとう

4

1 に答える 1

0

アラーム信号を使用することをお勧めします。

#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>

void timer_handler (int signum)
{
  struct timeval tval;
  gettimeofday(&tval, NULL);
  printf("Seconds: %ld\n",tval.tv_sec);
}

int main ()
{
  struct sigaction sa;
  struct itimerval timer;

  memset (&sa, 0, sizeof (sa));
  sa.sa_handler = &timer_handler;
  sigaction (SIGVTALRM, &sa, NULL);

  timer.it_value.tv_sec = 1;
  timer.it_value.tv_usec = 0;
  timer.it_interval.tv_sec = 1;
  timer.it_interval.tv_usec = 0;
  setitimer (ITIMER_VIRTUAL, &timer, NULL);

  while (1);
}

私の Mac (OS X 10.11.5) では、次のようになります。

./alarm
秒: 1468937712
秒: 1468937713
秒: 1468937714
秒: 1468937715
秒: 1468937716
秒: 1468937717
秒: 1468937718
秒: 1468937719
秒: 77 142683

編集

上記のコードは仮想タイマーを使用しています。これは、スレッドが実行されている間だけ作動します (したがって、ビジー ループに依存して高負荷が発生します)。リアル タイマーを使用すると、負荷を軽減できます。

#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <pthread.h>

void timer_handler (int signum)
{
  struct timeval tval;
  printf("Foo");
  gettimeofday(&tval, NULL);
  printf("Seconds: %ld\n",tval.tv_sec);
}

int main ()
{
  struct sigaction sa;
  struct itimerval timer;
  sa.sa_mask=0;
  sa.sa_flags=0;


  memset (&sa, 0, sizeof (sa));
  sa.sa_handler = &timer_handler;
  sigaction (SIGALRM, &sa, NULL);

  timer.it_value.tv_sec = 1;
  timer.it_value.tv_usec = 0;
  timer.it_interval.tv_sec = 1;
  timer.it_interval.tv_usec = 0;
  setitimer (ITIMER_REAL, &timer, NULL);

  while (1){
    pthread_yield_np();
  }
}

このアプローチは、基本的にタイマー ハンドラのみを実行します。したがって、OS は負荷を気にする必要はありません。ただし、ハードリアルタイムは、OS のリアルタイム機能 (存在する場合) によってのみ得られることを保証することに注意してください。

于 2016-07-19T14:22:56.880 に答える