以上的解决方案都没有回答问题。它们要么不能给出绝对的Unix时间,要么它们的准确性为1微秒。最受欢迎的解决方案是由jbenet提出的,但它很慢(约6000ns),即使它的返回结果表明如此,它也不计算纳秒。下面是针对jbenet和Dmitri B提出的两个解决方案以及我的想法的测试。您可以在不更改代码的情况下运行该代码。
第三个解决方案确实计算纳秒,并且能够快速地给出绝对Unix时间(约90ns)。因此,如果有人发现它有用,请在这里告诉我们:-)。我会坚持使用 Dmitri B的那个(在代码中是解决方案#1),因为它更适合我的需求。
我需要商业质量的替代clock_gettime()来进行pthread_…timed..调用,并发现这个讨论非常有帮助。谢谢大家。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <mach/mach_time.h>
#include <mach/mach.h>
#include <mach/clock.h>
#define BILLION 1000000000L
#define MILLION 1000000L
#define NORMALISE_TIMESPEC( ts, uint_milli ) \
do { \
ts.tv_sec += uint_milli / 1000u; \
ts.tv_nsec += (uint_milli % 1000u) * MILLION; \
ts.tv_sec += ts.tv_nsec / BILLION; \
ts.tv_nsec = ts.tv_nsec % BILLION; \
} while (0)
static mach_timebase_info_data_t timebase = { 0, 0 };
static struct timespec inittime = { 0, 0 };
static uint64_t initclock;
void init()
{
struct timeval micro;
if (mach_timebase_info(&timebase) != 0)
abort();
if (gettimeofday(µ, NULL) != 0)
abort();
initclock = mach_absolute_time();
inittime.tv_sec = micro.tv_sec;
inittime.tv_nsec = micro.tv_usec * 1000;
printf("\tinittime.tv_sec = %ld\n", inittime.tv_sec);
printf("\tinittime.tv_nsec = %ld\n", inittime.tv_nsec);
printf("\tinitclock = %ld\n", (long)initclock);
}
struct timespec get_abs_future_time_coarse(unsigned milli)
{
struct timespec future;
struct timeval micro = {0, 0};
(void) gettimeofday(µ, NULL);
future.tv_sec = micro.tv_sec;
future.tv_nsec = micro.tv_usec * 1000;
NORMALISE_TIMESPEC( future, milli );
return future;
}
struct timespec get_abs_future_time_served(unsigned milli)
{
struct timespec future;
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);
future.tv_sec = mts.tv_sec;
future.tv_nsec = mts.tv_nsec;
NORMALISE_TIMESPEC( future, milli );
return future;
}
struct timespec get_abs_future_time_fine(unsigned milli)
{
struct timespec future;
uint64_t clock;
uint64_t nano;
clock = mach_absolute_time() - initclock;
nano = clock * (uint64_t)timebase.numer / (uint64_t)timebase.denom;
future = inittime;
future.tv_sec += nano / BILLION;
future.tv_nsec += nano % BILLION;
NORMALISE_TIMESPEC( future, milli );
return future;
}
#define N 3
int main()
{
int i, j;
struct timespec time[3][N];
struct timespec (*get_abs_future_time[])(unsigned milli) =
{
&get_abs_future_time_coarse,
&get_abs_future_time_served,
&get_abs_future_time_fine
};
init();
for (j = 0; j < 3; j++)
for (i = 0; i < N; i++)
time[j][i] = get_abs_future_time[j](1500);
for (j = 0; j < 3; j++)
for (i = 0; i < N; i++)
printf("get_abs_future_time_%d() : %10ld.%09ld\n",
j, time[j][i].tv_sec, time[j][i].tv_nsec);
return 0;
}
#include <time.h>
? - pmgclock_gettime
。 - Delan Azabaniclock_gettime
,而Linux有。 - Delan Azabaniclock_gettime()
函数——正如James Wald在这个答案中所指出的。 - Jonathan Leffler