13

2 つの入力ソケットの FIFO キューを維持するソケット プログラムを作成しています。サービスするキューを決定するとき、プログラムは各キューから最新のタイムスタンプを取得します。

2 つの構造体を比較するための信頼できる方法が必要timevalです。を使用してみtimercmp()ましたが、使用している gcc のバージョンではサポートされておらず、ドキュメントには関数が POSIX に準拠していないと記載されています。

私は何をすべきか?

4

4 に答える 4

16

timercmp()libc(sys/time.h)の単なるマクロです:

# define timercmp(a, b, CMP)                                                  \
  (((a)->tv_sec == (b)->tv_sec) ?                                             \
   ((a)->tv_usec CMP (b)->tv_usec) :                                          \
   ((a)->tv_sec CMP (b)->tv_sec))

必要な場合timersub():

# define timersub(a, b, result)                                               \
  do {                                                                        \
    (result)->tv_sec = (a)->tv_sec - (b)->tv_sec;                             \
    (result)->tv_usec = (a)->tv_usec - (b)->tv_usec;                          \
    if ((result)->tv_usec < 0) {                                              \
      --(result)->tv_sec;                                                     \
      (result)->tv_usec += 1000000;                                           \
    }                                                                         \
  } while (0)
于 2009-12-07T05:55:41.290 に答える
7

グーグルはこの最初の結果timevalを与えます。そのページから:

struct timeval または struct timespec 型の 2 つの値を減算する必要があることがよくあります。これを行う最良の方法は次のとおりです。tv_sec メンバーが unsigned 型である特殊なオペレーティング システムでも動作します。

 /* Subtract the `struct timeval' values X and Y,
    storing the result in RESULT.
    Return 1 if the difference is negative, otherwise 0.  */

 int
 timeval_subtract (result, x, y)
      struct timeval *result, *x, *y;
 {
   /* Perform the carry for the later subtraction by updating y. */
   if (x->tv_usec < y->tv_usec) {
     int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
     y->tv_usec -= 1000000 * nsec;
     y->tv_sec += nsec;
   }
   if (x->tv_usec - y->tv_usec > 1000000) {
     int nsec = (x->tv_usec - y->tv_usec) / 1000000;
     y->tv_usec += 1000000 * nsec;
     y->tv_sec -= nsec;
   }

   /* Compute the time remaining to wait.
      tv_usec is certainly positive. */
   result->tv_sec = x->tv_sec - y->tv_sec;
   result->tv_usec = x->tv_usec - y->tv_usec;

   /* Return 1 if result is negative. */
   return x->tv_sec < y->tv_sec;
 }
于 2009-12-07T05:52:30.657 に答える
0

これは少し異なりますが、関連するロジックを明確に示していると思います。私は C でいくつかの MSP430 コードに取り組んでおり、timeval に非常によく似たタイムスタンプ構造体を持っていますが、usecs ではなく nsecs を使用しています。

このコードはすべてを正に保つので、unsigned int は正常に機能し、オーバーフローを回避します (私はそう思います)。もちろん、結果を除いて、渡されるタイムスタンプ/タイムバルも変更しません。

typedef struct timestamp {
    int32_t secs;
    int32_t nsecs;
} timestamp_t;

int timestamp_sub(timestamp_t * x, timestamp_t * y, timestamp_t * result){
    // returns 1 if difference is negative, 0 otherwise
    // result is the absolute value of the difference between x and y
    negative = 0;
    if( x->secs > y->secs ){
        if( x->nsecs > y->nsecs ){
            result->secs = x->secs - y->secs;
            result->nsecs = x->nsecs - y->nsecs;
        }else{
            result->secs = x->secs - y->secs - 1;
            result->nsecs = (1000*1000*1000) - y->nsecs + x->nsecs;
        }
    }else{
        if( x->secs == y->secs ){
            result->secs = 0;
            if( x->nsecs > y->nsecs ){
                result->nsecs = x->nsecs - y->nsecs;
            }else{
                negative = 1;
                result->nsecs = y->nsecs - x->nsecs;
            }
        }else{
            negative = 1;
            if( x->nsecs > y->nsecs ){
                result->secs = y->secs - x->secs - 1;
                result->nsecs = (1000*1000*1000) - x->nsecs + y->nsecs;
            }else{
                result->secs = y->secs - x->secs;
                result->nsecs = y->nsecs - x->nsecs;
            }
        }
    }
    return negative;
}
于 2012-05-07T05:10:48.827 に答える