Keine der oben genannten Lösungen beantwortet die Frage. Entweder geben sie Ihnen keine absolute Unix-Zeit oder ihre Genauigkeit beträgt 1 Mikrosekunde. Die beliebteste Lösung von jbenet ist langsam (~ 6000 ns) und zählt nicht in Nanosekunden, obwohl die Rückkehr dies nahelegt. Unten finden Sie einen Test für zwei von jbenet und Dmitri B vorgeschlagene Lösungen sowie meine Meinung dazu. Sie können den Code ohne Änderungen ausführen.
Die dritte Lösung zählt in Nanosekunden und gibt Ihnen eine relativ schnelle absolute Unix-Zeit (~ 90 ns). Also, wenn jemand es nützlich findet - bitte lassen Sie es uns alle hier wissen :-). Ich werde mich an die von Dmitri B halten (Lösung Nr. 1 im Code) - sie passt besser zu meinen Bedürfnissen.
Ich brauchte eine Alternative in kommerzieller Qualität zu clock_gettime (), um pthread_… timed .. -Aufrufe zu tätigen, und fand diese Diskussion sehr hilfreich. Danke Leute.
#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>
?