2016-09-29 7 views
3

Ich habe zwei einzelnen Thread Prozess A & B mit zwei msg Warteschlange [separate Warteschlange für Sende- und Empfangs] umgesetzt. Prozess A sendet eine Nachricht an B und wartet auf eine Antwort in der Empfangswarteschlange.Welcher Takt sollte für die Interprozesskommunikation in Linux verwendet werden?

Ich möchte einen Zeitstempel aus dem Prozess A senden B. zu verarbeiten, wenn B Prozess die Nachricht nach 10 Sekunden erhält, möchte ich von Prozeß B zu A. eine Fehlerzeichenfolge senden

Genauigkeit sollte in sein Millisekunden.

In Verfahren A i verwendet,

struct timespec msg_dispatch_time; 
    clock_gettime(CLOCK_REALTIME, &msg_dispatch_time); 
    : 
    : 
    add_timestamp_in_msg(msg, msg_dispatch_time); 
    : 
    if (msgsnd(msqid, msg, sizeof(msg), msgflg) == -1) 
     perror("msgop: msgsnd failed"); 

In Verfahren B,

struct timespec msg_dispatch_time; 
    struct timespec msg_receive_time; 
    : 
    clock_gettime(CLOCK_REALTIME, &msg_received_time); 
    : 
    if(!(time_diff(msg_received_time, msg_dispatch_time) >= 10)) 
     msgsnd(msqid, &sbuf, buf_length, msg_flag) 
    else 
    { 
     /*send the error string.*/ 
     //msgsnd(msgid,) 
    } 

Meine Frage ist,

1) Wie eine time_diff Funktion hier mit Millisekunden-Genauigkeit zu schreiben, um zu vergleichen, gegen 10 Sekunden?

if(!(time_diff(msg_received_time, msg_dispatch_time) >= 10)) 



    /********Existing time diff code******************/ 
    long int time_diff (struct timeval time1, struct timeval time2) 
    { 
     struct timeval diff, 

     if (time1.tv_usec < time2.tv_usec) { 
      time1.tv_usec += 1000000; 
      time1.tv_sec--; 
     } 
     diff.tv_usec = time1.tv_usec - time2.tv_usec; 
     diff.tv_sec = time1.tv_sec - time2.tv_sec;  
     return diff.tv_sec; //return the diff in second 
    } 

2) Ist clock_gettime in Ordnung, um über Prozess im selben System zu verwenden?

+1

'enum {NS_PER_SECOND = 1000000000}; void sub_timespec (Struktur Timespec t1, ​​Struktur Timespec t2, Struktur Timespec * td) { td-> tv_nsec = t2.tv_nsec - t1.tv_nsec; td-> tv_sec = t2.tv_sec - t1.tv_sec; if (td-> tv_sec> 0 && td-> tv_nsec <0) { td-> tv_nsec + = NS_PER_SECOND; td-> tv_sec-; } sonst if (td-> tv_sec < 0 && td-> tv_nsec> 0) { td-> tv_nsec - = NS_PER_SECOND; td-> tv_seC++; } } ' –

+1

Überprüfen Sie' timeval_subtract' in http://www.gnu.org/software/libc/manual/html_node/Elapsed.Time.html – PnotNP

+1

@NulledPointer: 'timeval_subtract()' ist für 'struct timeval' eher als 'struct timespec', oder? Aber die Konzepte können sicherlich auf den anderen Typ angewendet werden. –

Antwort

1

Wenn Sie den struct timespec Typen behalten mögen verwenden, dann empfehle ich für struct timespec Typen eines difftime() äquivalent unter Verwendung, das heißt

double difftimespec(const struct timespec after, const struct timespec before) 
{ 
    return (double)(after.tv_sec - before.tv_sec) 
     + (double)(after.tv_nsec - before.tv_nsec)/1000000000.0; 
} 

Aber ich denke, dass es eine bessere Option für Ihren allgemeinen Anwendungsfall besteht.

Wenn Sie zufrieden sind für Ihr Programm bis Jahr 2242 zu arbeiten, können Sie eine 64-Bit-Ganzzahl mit Vorzeichen verwenden, um die Anzahl von Nanosekunden seit der Epoche zu halten. Bei binären Nachrichten ist das Format viel einfacher zu handhaben als struct timespec. Im Wesentlichen:

#define _POSIX_C_SOURCE 200809L 
#include <stdint.h> 
#include <time.h> 

typedef int64_t  nstime; 
#define NSTIME_MIN INT64_MIN 
#define NSTIME_MAX INT64_MAX 

nstime nstime_realtime(void) 
{ 
    struct timespec ts; 

    if (clock_gettime(CLOCK_REALTIME, &ts)) 
     return NSTIME_MIN; 

    return ((nstime)ts.tv_sec * 1000000000) 
     + (nstime)ts.tv_nsec; 
} 

double nstime_secs(const nstime ns) 
{ 
    return (double)ns/1000000000.0; 
} 

struct timespec nstime_timespec(const nstime ns) 
{ 
    struct timespec ts; 

    if (ns < 0) { 
     ts.tv_sec = (time_t)(ns/-1000000000); 
     ts.tv_nsec = -(long)((-ns) % 1000000000); 
     if (ts.tv_nsec < 0L) { 
      ts.tv_sec--; 
      ts.tv_nsec += 1000000000L; 
     } 
    } else { 
     ts.tv_sec = (time_t)(ns/1000000000); 
     ts.tv_nsec = (long)(ns % 1000000000); 
    } 
} 

können Sie addieren und subtrahieren nstime Zeitstempel jede mögliche Weise Sie wollen, und sie sind geeignet für binäre Speicherung, auch (Byte-Reihenfolge (aka Endian) Fragen ungeachtet).

(Beachten Sie, dass der Code über ungetestet ist, und ich halte es für public domain/CC0.)


Mit clock_gettime() in Ordnung ist. Sowohl CLOCK_REALTIME als auch CLOCK_MONOTONIC sind systemweit, d. H. Sollten dieselben Ergebnisse in verschiedenen Prozessen berichten, wenn sie im selben physikalischen Moment ausgeführt werden.

CLOCK_REALTIME ist in allen POSIXy-Systemen verfügbar, aber CLOCK_MONOTONIC ist optional. Beide sind immun gegenüber Änderungen der Sommerzeit. Inkrementelle NTP-Anpassungen wirken sich auf beide aus. Manuelle Änderungen der Systemzeit durch einen Administrator wirken sich nur auf CLOCK_REALTIME aus. Die Epoche für CLOCK_REALTIME ist derzeit der 1. Januar 1970, 00:00:00, ist jedoch für CLOCK_MONOTONIC nicht spezifiziert.

Persönlich empfehle ich die Verwendung clock_gettime(CLOCK_REALTIME,), weil dann Ihre Anwendung über Prozesse in einem Cluster, nicht nur auf einem lokalen Computer sprechen kann; Clusterknoten können unterschiedliche Epochen für CLOCK_MONOTONIC verwenden.

Verwandte Themen