2009-12-07 15 views
10

मैं एक सॉकेट प्रोग्राम लिख रहा हूं जो दो इनपुट सॉकेट के लिए फीफो कतार बनाए रखता है। सेवा के लिए कौन सी कतार तय करते समय, कार्यक्रम प्रत्येक कतार से सबसे हालिया समय-टिकट खींचता है।मैं सी में दो टाइमस्टैम्प की तुलना कैसे करूं?

मुझे दो timeval structs की तुलना करने के लिए एक विश्वसनीय विधि की आवश्यकता है। मैंने timercmp() का उपयोग करने का प्रयास किया, लेकिन जीसीसी का मेरा संस्करण इसका समर्थन नहीं करता है, और दस्तावेज़ीकरण बताता है कि फ़ंक्शन POSIX अनुपालन नहीं है।

मुझे क्या करना चाहिए?

उत्तर

5

googling timevalthis first result दें। उस पृष्ठ से:

टाइप स्ट्रक्चर टाइमवल या स्ट्रक्चर टाइमपेक के दो मानों को घटाना अक्सर आवश्यक होता है। ऐसा करने का सबसे अच्छा तरीका यहां दिया गया है। यह कुछ असाधारण ऑपरेटिंग सिस्टम पर भी काम करता है जहां tv_sec सदस्य के पास एक हस्ताक्षरित प्रकार है।

# 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() की जरूरत है:

/* 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; 
} 
+1

टिप के लिए धन्यवाद, लेकिन मैं पहले से ही कोड का उपयोग कर रहा हूं। वास्तव में, मुझे एहसास हुआ कि मेरी समस्या क्या थी। Google की जांच के लिए धन्यवाद, शायद यह पहली बात है जिसे मैंने उत्तर के रूप में पोस्ट किया होगा। =) –

+2

स्पष्टीकरण के लिए, मुझे एहसास हुआ कि समय-समय पर 'tv_sec' और' tv_usec' मान होने के लिए समय-समय पर प्रारंभ किया गया था। कतारों को ठीक से शुरू करने के लिए 'gettimeofday() 'का उपयोग करके समस्या को हल किया गया। सहायता का शुक्रिया। =) –

+0

2 एशेलली, मैं जोड़ूंगा, कि आईएमएचओ दूसरी स्थिति को 'x-> tv_usec - y-> tv_usec> = 1000000' को बदलने के लिए बेहतर है ताकि '5/1000000' से' 6/0'। – Kolyunya

11

timercmp() libc में सिर्फ एक मैक्रो (sys/time.h) है

# 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) 
+0

से लिनक्स पर संकलन करते समय _BSD_SOURCE मैक्रो को परिभाषित करने की आवश्यकता है। –

0

यह थोड़ा अलग है, लेकिन मैं स्पष्ट रूप से सोचने शामिल तर्क शामिल है। मैं सी में कुछ एमएसपी 430 कोड पर काम कर रहा हूं, और समय सारिणी के समान समय सारिणी संरचना है, लेकिन उपयोग के बजाय nsecs के साथ।

यह कोड सबकुछ सकारात्मक रखता है, इसलिए हस्ताक्षरित इन्स ठीक काम करेंगे, और ओवरफ्लो (मुझे लगता है) से बचाता है। यह कोर्स के परिणाम को छोड़कर, टाइमस्टैम्प/टाइमवॉल पास होने में भी संशोधन नहीं करता है।

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; 
} 
+1

फ़्लोटिंग-पॉइंट '1e9' के बजाय आप पूर्णांक' 1000000000' (या '1000 * 1000 * 1000' अगर आप पसंद करते हैं) का उपयोग करना बेहतर कर रहे हैं, क्योंकि पूर्व अधिक कुशल होने की संभावना है। –

संबंधित मुद्दे