2015-07-07 16 views
7

Oltre alla differenza di precisione, quali sono le differenze tra e struct timespec? Se ho bisogno di meno precisione di μs (ad esempio, millisecondi), perché dovrei usarne uno rispetto all'altro?c in tempo reale vs timespec

Sul mio compilatore (GCC per ARM):

/* POSIX.1b structure for a time value. This is like a `struct timeval' but 
    has nanoseconds instead of microseconds. */ 
struct timespec 
    { 
    __time_t tv_sec;  /* Seconds. */ 
    __syscall_slong_t tv_nsec; /* Nanoseconds. */ 
    }; 

/* A time value that is accurate to the nearest 
    microsecond but also has a range of years. */ 
struct timeval 
    { 
    __time_t tv_sec;  /* Seconds. */ 
    __suseconds_t tv_usec; /* Microseconds. */ 
    }; 

Con entrambi __syscall_slong_t e __suseconds_t definito come una "parola lunga".

+3

Si utilizza la struttura corretta per le chiamate di sistema che si intende utilizzare - 'struct timeval' per' gettimeofday() '(e' select() '), e' struct timespec' per 'clock_gettime()'.Per l'elaborazione interna, è possibile utilizzare uno o entrambi, come è conveniente per te. La conversione tra i due è relativamente indolore; input e output richiedono un minimo di attenzione (principalmente assicurandosi che gli zeri iniziali per la parte frazionaria vengano stampati e scansionati correttamente quando necessario). BSD e Mac OS X forniscono alcune primitive funzioni aritmetiche e di confronto per 'struct timeval'; non esiste un analogo per 'struct timespec'. –

+1

Si dovrebbe guardare [Perché C ha così tanti tipi diversi] (http://stackoverflow.com/questions/31157164/) che chiede anche 'struct timeval'. –

risposta

12

Penso che sia davvero solo questione di compatibilità con API [in]. Le chiamate POSIX-y come pselect() e clock_gettime() utilizzano struct timespec. Varie chiamate al filesystem come utimes() e alcune chiamate Linux assortite come gettimeofday() e select(), utilizzare struct timeval. Ampiamente generalizzando da poche pagine man, sospetto che struct timeval abbia un'eredità BSD mentre struct timespec è POSIX.

Se si eseguono misurazioni intervallate, non c'è motivo di non sfruttare la precisione extra di clock_gettime() - ma attenzione che di solito è l'hardware, non il file di intestazione, che limita la precisione della misurazione. Dividere per un milione a scopo di visualizzazione non è certo migliore o peggiore della divisione di mille. Inoltre, Mac OS X does not support clock_gettime().

Ma se si sta facendo molta manipolazione del tempo di file, potrebbe essere più logico utilizzare lo utilizzato in API come utimes(). struct timeval ha anche alcune funzioni di confronto su Linux, BSD e Mac OS X, ad es. timercmp(), timersub() (di nuovo, vedere le pagine man).

Prenderei la decisione in base alle API che intendi utilizzare, piuttosto che alle strutture stesse. (O scrivi una classe wrapper con i metodi di conversione, se necessario.)

+0

La mia versione corrente di Mac OS X (10.12) supporta 'clock_gettime'. – ioquatix

2

Entrambe sono definite AFAIK per POSIX.1-2001, quindi dal punto di vista della portabilità, non importa quale si utilizza. La risposta più semplice è: usa quello di cui hai bisogno per l'API che intendi chiamare.

ci potrebbe essere un vantaggio dimensione dipende dalla piattaforma utilizzando struct timeval:

Il tipo suseconds_t sarà un firmata tipo intero grado di memorizzare valori almeno nell'intervallo [-1, 1000000].

in struct timespec il secondo membro è di tipo long. Un int sarebbe sufficiente su una piattaforma a 32 bit per soddisfare i requisiti suseconds_t. Ma, su un sistema a 64 bit, lo standard time_t è in genere a 64 bit, costringendo quindi la struttura a eseguire il pad a 16 byte in ogni caso. Quindi un vantaggio in termini di dimensioni è - improbabile.

+3

Sì, entrambi sono ancora POSIX ma dal POSIX.1-2008 + TC1 alcune funzioni che usano 'struct timeval' sono contrassegnate come obsolete. 'struct timespec' fa anche parte dello standard ISO C da C11. – cremno

1

Personalmente, non ne uso nessuno. Preferisco esprimere il tempo come semplice int64_t perché questo rende i calcoli del tempo estremamente semplici e, se necessario, la conversione in struct timeval o struct timespec non è un problema. Anche se desideri una precisione di nanosecondi, lo standard int64_t può esprimere un intervallo di quasi 585 anni. Se hai solo bisogno di millisecondi, hai una durata di quasi 585 milioni di anni.