2016-05-20 21 views
2

Das folgende C-Programm erhält zuerst die Uhrzeit mit clock_gettime(), und erstellt dann eine Datei und liest seine Änderungszeit aus. Auf meinem System ist die Datei mtime ein älterer Zeitstempel als das Ergebnis von clock_gettime(). Meine Frage ist, wie dies erklärt werden kann, und gibt es einen Standard (wie POSIX), der angeben würde, dass beide in Ordnung sein müssen?Timing skew mit clock_gettime und struct stat.mtim

/* Compile as C11 */ 
#define _POSIX_C_SOURCE 200809L 

#include <time.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <unistd.h> 

int main() 
{ 
    struct timespec buf_start; 

    int r= clock_gettime(CLOCK_REALTIME, &buf_start); 
    if (r != 0) { 
     perror("clock_gettime"); 
     exit(1); 
    } 

    FILE *file= fopen("A", "w"); 
    if (file == NULL) { 
     perror("A"); 
     exit(1); 
    } 
    r= fputs("aaa\n", file); 
    if (r == EOF) { 
     perror("A"); 
     exit(1); 
    } 
    r= fclose(file); 
    if (r != 0) { 
     perror("A"); 
     exit(1); 
    } 

    struct stat stat_file; 

    r= stat("A", &stat_file); 
    if (r != 0) { 
     perror("A"); 
     exit(1); 
    } 

    r= printf("%ld.%9ld\n%ld.%9ld\n", 
      buf_start.tv_sec, buf_start.tv_nsec, 
      stat_file.st_mtim.tv_sec, stat_file.st_mtim.tv_nsec); 
    if (r < 0) { 
     perror("printf"); 
     exit(1); 
    } 

    exit(0); 
} 

Auf meinem System (Ubuntu 14.04), mit gcc 4.8.4 und einem ext4-Dateisystem ist die Ausgabe:

1463778756.834469527 
1463778756.832709123 

Das heißt, die Startzeit des Programms als 2 ms gemeldet nach die Bearbeitungszeit der Datei.

EDIT: Mit CLOCK_REALTIME_COARSE sind die beiden resultierenden Zeitstempel bis auf die Nanosekunde genau gleich.

EDIT: Die Auflösung von clock_getres (CLOCK_REALTIME, ...) ist eine Nanosekunde.

EDIT: Dateisysteminformationen hinzugefügt.

+1

Welche Art von Ergebnissen erhalten Sie mit CLOCK_REALTIME_COARSE? – nos

+0

Ich bekomme 1463786166.436852447 und 1463786166.436852447, d. H. Die gleiche Nummer –

+0

Ich frage mich, ob das Dateisystem seinen Zeitstempel von dem gleichen Mechanismus erhält, der von CLOCK_REALTIME_COARSE –

Antwort

1

Basierend auf der Forschung von Benutzern Nos und auf dem angegebenen Link, hier eine Antwort auf die Frage lautet: (Disclaimer: Ich bin die ursprüngliche Frage Fragesteller)

Unter Linux werden Zeitstempel in ext4 mit Nanosekunde Präzision gespeichert , aber der Zeitstempel selbst wird zwischengespeichert. In regelmäßigen Abständen ermittelt der Linux-Kernel die (in der Regel teure) Nanosekunden-Präzisionszeit und speichert sie in einer globalen Variablen. Bis zur nächsten Aktualisierung dieser Variablen werden alle auf die Festplatte geschriebenen Zeitstempel (oder zu einigen anderen Datenstrukturen) auf diesen Wert und nicht auf die aktuelle Zeit gesetzt. Daher sind die Zeitstempel von Dateien in einem ext4-Dateisystem etwas zu alt. Dieser Fehler liegt in der Größenordnung von einigen Millisekunden.

Auf der anderen Seite gibt das Aufrufen von clock_gettime(), um die aktuelle Zeit zu erhalten, die (teuer zu berechnen) hochpräzise aktuelle Zeit zurück.

Soweit Standards wie POSIX gehen, konnte ich keine Aussage über Programme wie das in der Frage gegebene finden. Ich würde annehmen, dass solche Fragen als Teil eines "Echtzeitverhaltens" betrachtet werden und nicht Teil der üblichen Betriebssystemschnittstelle sind.

Praktisch kann man CLOCK_REALTIME_COARSE verwenden, um "Dateisystem-kompatible" Zeitstempel zu erhalten. Dies ist jedoch Linux-spezifisch, und die Tatsache, dass es funktioniert, basiert auch auf Wissen über das interne Arbeiten von ext4 und kann sich in Zukunft ohne Ankündigung ändern.

Für den POSIX-Standard wünschte ich, dass es ein Flag CLOCK_FILESYSTEM oder ähnliches gäbe, das garantieren würde, dass Programme wie das in der Frage angegebene wie erwartet funktionieren. Dies würde auch clock_getres (CLOCK_FILESYSTEM) ermöglichen, die tatsächliche Granularität dieses Takts zurückzugeben.