2016-09-29 38 views
3

我已經實現了兩個單線程進程A & B,帶有兩個msg隊列[獨立的發送和接收隊列]。進程A將向B發送消息並等待接收隊列中的回覆。哪個時鐘應該用於linux中的進程間通信?

我想從進程A發送時間戳如果過程B之後10秒接收消息處理B.,我想從處理B發送一個錯誤串A.

精度應該在毫秒。

在方法A,我用,

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"); 

在方法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,) 
    } 

我的問題是,

1)如何在這裏寫一個time_diff功能與毫秒級精確度比較對10秒?

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)clock_gettime可以在同一個系統的進程中使用嗎?

+1

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

+1

在http://www.gnu.org/software/libc/manual/html_node/Elapsed-Time.html檢查'timeval_subtract' – PnotNP

+1

@NulledPointer:'timeval_subtract()'用於'struct timeval'而非比'struct timespec',不是嗎?但這些概念當然可以應用於其他類型。 –

回答

1

如果您希望繼續使用struct timespec類型,那麼我建議使用相當於difftime()struct timespec型,即

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

不過,我認爲存在着對你的整體使用情況下更好的選擇。

如果你對你的程序工作到2242年滿意,你可以使用一個64位有符號整數來保存Epoch以來的納秒數。對於二進制消息,這是一種比struct timespec更容易處理的格式。本質:

#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); 
    } 
} 

可以加減法,nstime時間戳你希望的任何方式,以及它們適用於二進制存儲,太(字節順序(又名字節序)的問題仍然)。

(請注意,上面的代碼是未經測試,我認爲這是公共領域/ CC0)


使用clock_gettime()是罰款。 CLOCK_REALTIMECLOCK_MONOTONIC都是系統範圍的,即,如果在相同的物理時刻執行,則應該在不同的過程中報告完全相同的結果。

CLOCK_REALTIME適用於所有POSIXy系統,但CLOCK_MONOTONIC是可選的。兩者都不受日光節約時間變化的影響。增量NTP調整會影響兩者。管理員手動更改系統時間僅影響CLOCK_REALTIMECLOCK_REALTIME的時代目前是1970年1月1日的00:00:00,但對於CLOCK_MONOTONIC沒有指定。我個人建議使用clock_gettime(CLOCK_REALTIME,),因爲那樣你的應用程序就可以跨集羣中的進程進行對話,而不僅僅是在本地機器上;羣集節點可能會爲CLOCK_MONOTONIC使用不同的時期。

相關問題