只需使用马赫时间 。
它是公共API,它可以在macOS,iOS和tvOS上运行,并且可以在沙箱内运行。
马赫时间返回一个抽象时间单位,我通常称其为“时钟刻度”。时钟滴答的长度是系统特定的,取决于CPU。在当前的英特尔系统上,时钟节拍实际上只有一个纳秒,但您不能依赖于此(对于ARM可能不同,对于PowerPC CPU它肯定不同)。该系统还可以告诉您转换因子,将时钟滴答转换为纳秒和纳秒以作为时钟滴答(这个因子是静态的,在运行时不会改变)。当系统启动时,时钟开始于0
,然后随着每个时钟周期单调增加,因此您还可以使用Mach Time来获得系统的正常运行时间(当然,正常运行时间是单调的!)。
下面是一些代码:
#include <stdio.h>
#include <inttypes.h>
#include <mach/mach_time.h>
int main () {
uint64_t clockTicksSinceSystemBoot = mach_absolute_time();
printf("Clock ticks since system boot: %"PRIu64"\n",
clockTicksSinceSystemBoot
);
static mach_timebase_info_data_t timebase;
mach_timebase_info(&timebase);
// Cast to double is required to make this a floating point devision,
// otherwise it would be an interger division and only the result would
// be converted to floating point!
double clockTicksToNanosecons = (double)timebase.numer/timebase.denom;
uint64_t systemUptimeNanoseconds = (uint64_t)(
clockTicksToNanosecons * clockTicksSinceSystemBoot
);
uint64_t systemUptimeSeconds = systemUptimeNanoseconds/(1000 * 1000 * 1000);
printf("System uptime: %"PRIu64" seconds\n", systemUptimeSeconds);
}
你也可以把一个线程睡眠状态,直到一定时间马赫已经达到。下面是一些代码:
// Sleep for 750 ns
uint64_t machTimeNow = mach_absolute_time();
uint64_t clockTicksToSleep = (uint64_t)(750/clockTicksToNanosecons);
uint64_t machTimeIn750ns = machTimeNow + clockTicksToSleep;
mach_wait_until(machTimeIn750ns);
马赫时间没有联系任何时钟时间,你可以玩你的系统日期和时间设置,只要你喜欢,这不会对马赫时间任何影响。
虽然有一个特殊的考虑,可能会使马赫时间不适合某些使用情况:T 当您的系统睡着时CPU时钟不运行!因此,如果您让线程等待5分钟,1分钟后系统进入睡眠状态并保持睡眠30分钟,则线程在系统醒来后仍等待4分钟,因为30分钟的睡眠时间不会计数!在那段时间CPU时钟也在休息。然而在其他情况下,这正是你想要发生的事情。
马赫时间也是测量时间的一种非常精确的方法。下面是显示该任务的一些代码:再次甚至
// Measure time
uint64_t machTimeBegin = mach_absolute_time();
sleep(1);
uint64_t machTimeEnd = mach_absolute_time();
uint64_t machTimePassed = machTimeEnd - machTimeBegin;
uint64_t timePassedNS = (uint64_t)(
machTimePassed * clockTicksToNanosecons
);
printf("Thread slept for: %"PRIu64" ns\n", timePassedNS);
你会看到该线程不睡了整整一秒,这是因为它需要一些时间来把一个线程睡眠,唤醒回来当唤醒时,如果当前所有核心已经在忙于运行线程,它将不会立即获得CPU时间。
据我所知,'CLOCK_MONOTONIC'不保证该值不会漂移,也不存在线程关联问题。 – zneak 2012-07-27 02:05:56
稍微超过我的脑海,但'mach_absolute_time'确实使用rtdsc,可以从[source](http://www.opensource.apple.com/source/Libc/Libc-320.1.3/i386/mach /mach_absolute_time.c“mach_absolute_time.c”)。 – cobbal 2012-07-27 02:06:54
@cobbal:感谢您的发现!这绝对是为我规定mach_absolute_time。它可用于快速,短时的测量,因为该值可能会漂移。 – Brett 2012-07-27 02:11:26