Linux和OS X上的C语言中的ns精度单调时钟

时间:2014-02-09 22:02:31

标签: c linux macos time

clock_gettime(CLOCK_MONOTONIC, ...)在Linux中可用,但在OS X中不可用.Mach计时器在OS X中可用,但在Linux中不可用。

如何在C和Linux和OS X上同时获得ns精度单调时钟?

2 个答案:

答案 0 :(得分:8)

/* 
This is based on the snippet current_utc_time.c from:
https://gist.github.com/jbenet/1087739

On OS X, compile with: gcc get_monotonic_time.c
   Linux, compile with: gcc get_monotonic_time.c -lrt
*/

#include <time.h>
#include <sys/time.h>
#include <stdio.h>

#ifdef __MACH__
#include <mach/clock.h>
#include <mach/mach.h>
#endif

// Use clock_gettime in linux, clock_get_time in OS X.
void get_monotonic_time(struct timespec *ts){
#ifdef __MACH__
  clock_serv_t cclock;
  mach_timespec_t mts;
  host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
  clock_get_time(cclock, &mts);
  mach_port_deallocate(mach_task_self(), cclock);
  ts->tv_sec = mts.tv_sec;
  ts->tv_nsec = mts.tv_nsec;
#else
  clock_gettime(CLOCK_MONOTONIC, ts);
#endif
}

double get_elapsed_time(struct timespec *before, struct timespec *after){
  double deltat_s  = after->tv_sec - before->tv_sec;
  double deltat_ns = after->tv_nsec - before->tv_nsec;
  return deltat_s + deltat_ns*1e-9;
}

int main(){

  // Do something and time how long it takes.
  struct timespec before, after;
  get_monotonic_time(&before);
  double sum=0.;
  unsigned u;
  for(u=1; u<100000000; u++)
    sum += 1./u/u;
  get_monotonic_time(&after);
  printf("sum = %e\n", sum);
  printf("deltaT = %e s\n", get_elapsed_time(&before,&after));

}

答案 1 :(得分:0)

I used the answer by Douglas (accepted answer), his references and other examples floating around the internet (such as this question).

This answer is to include my version of the code which emulates the clock_gettime for CLOCK_REALTIME and CLOCK_MONOTONIC. It also emulates the function clock_nanosleep() for absolute monotonic time. The code is hosted on GitHub here.

For it to work, the only additional bit needed in your code is

#ifdef __MACH__
timing_mach_init();
#endif

then use clock_gettime() and clock_nanosleep_abstime() as if you were using a system that is actually POSIX compliant (with realtime extensions).