便携式获取时间的方法

时间:2015-07-04 05:40:54

标签: c loops timer

由于Mac OS X不支持获取时间,我发现这个要点以便携式方式使用clock_gettime基金:

void current_utc_time(struct timespec *ts) {

#ifdef __MACH__ // OS X does not have clock_gettime, use clock_get_time
    clock_serv_t cclock;
    mach_timespec_t mts;
    host_get_clock_service(mach_host_self(), CALENDAR_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_REALTIME, ts);
#endif
}

像这样使用它

struct timespec requestStart;
current_utc_time(&requestStart);
printf("start: s:  %lu\n", requestStart.tv_sec);
printf("start: ns: %lu\n", requestStart.tv_nsec);
start: s:  1435988139
start: ns: 202015000

我试图从这段代码中获取秒和毫秒值,这是从纳秒值获得毫秒的正确方法吗?

printf("total: ms:  %lu\n", (requestStart.tv_nsec - requestEnd.tv_nsec) / (unsigned long)1000000);

如果是这样,我如何获得秒值?如果不是,我怎么能得到毫秒和秒值?

修改 在回应第一条评论时,我主要是寻找一种让代码尽可能便携的方法。

2 个答案:

答案 0 :(得分:2)

如果您想要便携性,只需使用gettimeofday即可。这应该适用于所有地方clock_gettime似乎是 Linux特定的是一个相对较新的Posix介绍。

转换时:struct timeval(由gettimeofday和其他旧函数使用)使用微秒。较新的struct timespec使用纳秒。所以要来回转换,你会乘以或除以1000。

计算差异时,你必须担心进位/溢出,所以表达

(requestStart.tv_nsec - requestEnd.tv_nsec) / (unsigned long)1000000

是不正确的,原因有两个:差异可能是负面的(也就是说,如果时间从123.456变为124.321),并且你将它缩小太多。

当我计时某些操作时,我通常会这样做:

struct timeval before, after, elapsed;
gettimeofday(&before, NULL);
sleep(1);
gettimeofday(&after, NULL);
elapsed.tv_sec = after.tv_sec - before.tv_sec;
if(after.tv_usec >= before.tv_usec)
        elapsed.tv_usec = after.tv_usec - before.tv_usec;
else    {
        elapsed.tv_sec--;
        elapsed.tv_usec = 1000000 + after.tv_usec - before.tv_usec;
        }
printf("elapsed: %d.%06ld\n", (int)elapsed.tv_sec, (long)elapsed.tv_usec);

如果我想要struct timespec(使用纳秒),我会乘以1000:

struct timespec elapsed2;
elapsed2.tv_sec = elapsed.tv_sec;
elapsed2.tv_nsec = elapsed.tv_usec * 1000;
printf("elapsed: %d.%09ld\n", (int)elapsed2.tv_sec, (long)elapsed2.tv_nsec);

要从struct timespec转换回struct timeval,我除以1000:

struct timeval elapsed3;
elapsed3.tv_sec = elapsed2.tv_sec;
elapsed3.tv_usec = elapsed2.tv_nsec / 1000;

另一个有用的东西是将秒和子秒作为浮点:

double e = (double)elapsed.tv_sec + elapsed.tv_usec / 1e6;
double e2 = (double)elapsed2.tv_sec + elapsed2.tv_nsec / 1e9;
printf("float: %f %f\n", e, e2);

(事实证明,编写此类代码时可能存在细微差别,具体取决于tv_sectv_usectv_nsec的实际类型,以及"您的编译器可能会选择给您提供帮助"警告。请参阅this question。)

答案 1 :(得分:0)

#import <time.h>
#import <sys/timeb.h>

struct timeb timebCurrentTime;

ftime(&timebCurrentTime);
double y = (double)timebCurrentTime.time + (double)timebCurrentTime.millitm / 1000;//current time in sec since 1970-01-01 00:00:00 +0000 (UTC)