My c-function using difftime returns 65535 sometimes

后端 未结 2 1816
隐瞒了意图╮
隐瞒了意图╮ 2021-01-26 00:05

I have a function that uses difftime to detect the time in seconds since the communication heartbeat has stopped. This function could run as fast as every 50 milliseconds. The

相关标签:
2条回答
  • 2021-01-26 00:48

    difftime() is of use on systems where time_t supports time to a higher resolution than integral seconds. Although allowed, I've never encountered such a system - I don't imagine one exists. On POSIX systems specifically, time_t is measured in integral seconds, and difftime() is equivalent to arithmetic subtraction of its arguments, so in fact you are better off simply using:

    commlost_secs_cur += current_time - previous_time ;
    

    That said, your implementation is somewhat over-complex, rather than accumulating time since the previous call, which may be smaller than the clock resolution, you could simply time-stamp the last heartbeat observed and return time since then:

    int commlost(uint16_t heartbeat_read_cur)
    {  
        time_t current_time = time(0) ;  
        static time_t heartbeat_timestamp = 0 ; 
        static uint16_t heartbeat_read_prev  ;
    
        // If first time, or heartbeat changed...
        if( heartbeat_timestamp == 0 || heartbeat_read_prev != heartbeat_read_cur)
        {
            // ... timestamp heartbeat
            heartbeat_timestamp = time(0) ;
    
            // ... keep last heartbeat
            heartbeat_read_prev = heartbeat_read_cur ;
        }
    
        // Return seconds since last heartbeat timestamp
        return current_time - heartbeat_timestamp ;
    }
    

    I am not sure why you would use uint16_t for this; there is little or no advantage unless it is for compatibility with some specific protocol or file format.

    0 讨论(0)
  • 2021-01-26 01:08

    Before querying time, read the time(7) man page (and read it again).

    The, I suggest using clock_gettime(2) with e.g. CLOCK_MONOTONIC or CLOCK_REALTIME, and preferably use double for time calculations (since a struct timespec is generally larger than any integral type).

    Don't use uint16_t for such time calculations.

    Try using

    inline double double_gettime (clockid_t cid) {
      struct timespec ts = {0,0};
      clock_gettime(cid, &ts);
      return (double)ts.tv_sec + 1.0e-9*ts.tv_nsec;
    }
    

    You might want to make that function fancier, by testing if clock_gettime is failing and giving NAN when it fails! This is left as an exercise to the reader. You could also, for CLOCK_REALTIME etc, measure the difference between some time at start of process and the current time (i.e. compute a struct timespec of differences and convert that difference to a double)

    Then things like

    double tstart = double_gettime(CLOCK_REALTIME);
    some_long_computation();
    double tend = double_gettime(CLOCK_REALTIME);
    printf ("needed %f seconds to compute\n", tend-tstart);
    

    See also clock(3)

    0 讨论(0)
提交回复
热议问题