上面的解决方案都不能回答这个问题。他们要么没有给您绝对的Unix时间,要么它们的精度为1微秒。jbenet最受欢迎的解决方案是速度很慢(〜6000ns),即使返回表明如此,也不会以纳秒为单位。下面是jbenet和Dmitri B建议的2种解决方案的测试,以及我对此的看法。您可以运行代码而无需更改。
第三个解决方案的确以纳秒为单位,并为您提供了相当快的Unix绝对时间(〜90ns)。因此,如果有人觉得它有用-请在这里让我们所有人知道:-)。我将坚持使用Dmitri B(代码中的解决方案#1)中的一种-更好地满足我的需求。
我需要替代clock_gettime()的商业质量来进行pthread_…timed ..调用,并且发现此讨论非常有帮助。多谢你们。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h> /* gettimeofday */
#include <mach/mach_time.h> /* mach_absolute_time */
#include <mach/mach.h> /* host_get_clock_service, mach_... */
#include <mach/clock.h> /* clock_get_time */
#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>
吗