4

X (たとえば 5) 秒ごとに関数を呼び出す必要があり、以下のコードでそれを行います。

しかし、コードの実行をブロックしています。のように機能させたいのでsetitimer()、(たとえば) 5 秒ごとに関数を呼び出して、何か他のことを行うことができます。

   #include <sys/timerfd.h>
   #include <time.h>
   #include <unistd.h>
   #include <stdlib.h>
   #include <stdio.h>
   #include <stdint.h>        /* Definition of uint64_t */

   #define handle_error(msg) \
           do { perror(msg); exit(EXIT_FAILURE); } while (0)

   int
   main(int argc, char *argv[])
   {
       struct itimerspec new_value;
       int max_exp, fd;
       struct timespec now;
       uint64_t exp, tot_exp;
       ssize_t s;

       if (clock_gettime(CLOCK_REALTIME, &now) == -1)
           handle_error("clock_gettime");

       /* Create a CLOCK_REALTIME absolute timer with initial
          expiration and interval as specified in command line */

       new_value.it_value.tv_sec = now.tv_sec + 1; 
       new_value.it_value.tv_nsec = now.tv_nsec;

       new_value.it_interval.tv_sec = 5;
       new_value.it_interval.tv_nsec = 0;
       max_exp = 5; //say 5 times

       fd = timerfd_create(CLOCK_REALTIME, 0);
       if (fd == -1)
           handle_error("timerfd_create");

       if (timerfd_settime(fd, TFD_TIMER_ABSTIME, &new_value, NULL) == -1)
           handle_error("timerfd_settime");

       printf("timer started\n");
       for (tot_exp = 0; tot_exp < max_exp;) {
           s = read(fd, &exp, sizeof(uint64_t));
           if (s != sizeof(uint64_t))
               handle_error("read");

           tot_exp += exp;
           printf("read: %llu; total=%llu\n",
                   (unsigned long long) exp,
                   (unsigned long long) tot_exp);
       }
    //Do something else ?
    //while(1);
       exit(EXIT_SUCCESS);
   }

編集 もう1つ質問があります。上記のコードでこれらの行を変更すると、

   new_value.it_interval.tv_sec = 5;
   new_value.it_interval.tv_nsec = 0;

   new_value.it_interval.tv_sec = 0;
   new_value.it_interval.tv_nsec = 5000000000;

5秒の遅延がないことがわかります。ここで何が起こっているのですか?

4

2 に答える 2

2

poll(2) (またはselect(2)時代遅れになりがちな古いシステムコール)のような多重化システムコールの使用方法を理解し、それらを使用して、 timerfd_create(2)によって取得されたファイル記述子の可読性をテストする前にテストする必要がありますread(2)

ただし、その呼び出しが成功しtimerfd_createた場合にのみ機能することに注意してください。readそのため、fd が読み取り不能であると言われた場合にのみ、他のpollことを行うことができます。他の何かが速くなければならない (5 秒未満)。

libevent (wrapping )などのイベント ループ ライブラリを調査することをお勧めしますpoll。グラフィカル アプリケーションを (Qt または Gtk を使用して) コーディングしている場合、それには既に独自のイベント ループがあります。十分に賢い場合は、 を使用せずに 5 秒の期間を実行しtimerfd_create、イベント ループを介して実行できます (に指定されたタイムアウトを慎重に設定するpollなどにより)。

補遺:

tv_nsecフィールドは常に負ではなく、1000000000 (1 秒のナノ秒数) 未満である必要があります。

于 2012-09-19T16:48:05.143 に答える
0

timerfd を使用しなければならない理由はありますか? アラームをスケジュールし、関数を呼び出す SIGALRM のハンドラを作成するだけです。

シグナルを使用したくない場合は、タイマー fd でブロックする追加のスレッドを作成し、メイン スレッドで通常どおり続行します。

どちらも気に入らず、待っている間に仕事をしたい場合は、投票する必要があります。バジルが示唆するようにそれを行うことも、現在の時刻を保存して、ポーリングするたびに確認して、目的の期間が経過したかどうかを確認することもできます。

于 2012-09-19T17:00:25.943 に答える