2016-09-29 7 views
3

Я реализовал два процесса с одним потоком A & B с двумя очередями msg [отдельная очередь для отправки и получения]. Процесс A отправит сообщение в B и ждет ответа в очереди приема.Какие часы следует использовать для взаимодействия между процессами в Linux?

Хочу послать временную метку из процесса А для обработки B. Если процесс В принимает сообщение после того, как 10 секунд, я хочу, чтобы отправить строку ошибки от процесса B к 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; if (td-> tv_sec> 0 && td-> tv_nsec <0) { td-> tv_nsec + = NS_PER_SECOND; td-> tv_sec--; } else if (td-> tv_sec < 0 && td-> tv_nsec> 0) {td-> tv_nsec - = NS_PER_SECOND; td-> tv_seC++; } } '' –

+1

Проверка timeval_subtract' в http://www.gnu.org/software/libc/manual/html_node/Elapsed-Time.html – 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-разрядное целое число со знаком, чтобы удерживать число наносекунд с эпохи. Для двоичных сообщений этот формат намного проще, чем 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 временные метки так, как вы хотите, и они пригодны для бинарного хранения, тоже (порядком байтов (он же) вопросы порядка следования байтов несмотря на это).

(Обратите внимание, что приведенный выше код не тестировался, и я считаю это общественное достояние/СС0.)


Использование clock_gettime() прекрасно. Оба CLOCK_REALTIME и CLOCK_MONOTONIC являются общесистемными, то есть должны сообщать о тех же результатах в разных процессах, если они выполняются в тот же физический момент.

CLOCK_REALTIME доступен во всех системах POSIXy, но CLOCK_MONOTONIC не является обязательным. Оба невосприимчивы к изменениям на летнее время. Инкрементальные корректировки NTP влияют на оба. Ручное изменение системного времени администратором влияет только на CLOCK_REALTIME. Эпоха для CLOCK_REALTIME в настоящее время 1 января 1970 года, 00:00:00, но она не указана для CLOCK_MONOTONIC.

Лично я рекомендую использовать clock_gettime(CLOCK_REALTIME,), потому что тогда ваше приложение может разговаривать через процессы в кластере, а не только на локальной машине; узлы кластера могут использовать разные эпохи для CLOCK_MONOTONIC.