Необходимо учитывать tv_sec
член структуры при расчете разницы во времени между двумя значениями, возвращаемыми clock_gettime()
.
tv_nsec
- это числонаносекунд в течение текущей секунды.Он колеблется (в теории) от 0 до 999 999 999.Это позволяет хранить целое число целых секунд в tv_sec
и долю секунды в tv_nsec
.Фактическое решение - другая проблема: см. clock_getres()
.Например, на Mac разрешение составляет микросекунды, хотя они выражаются в наносекундах.
Рассмотрите возможность использования кода, подобного следующему:
#include <stdio.h>
#include <time.h>
#include <unistd.h>
enum { NS_PER_SECOND = 1000000000 };
void sub_timespec(struct timespec t1, struct timespec t2, struct timespec *td)
{
td->tv_nsec = t2.tv_nsec - t1.tv_nsec;
td->tv_sec = t2.tv_sec - t1.tv_sec;
if (td->tv_sec > 0 && td->tv_nsec < 0)
{
td->tv_nsec += NS_PER_SECOND;
td->tv_sec--;
}
else if (td->tv_sec < 0 && td->tv_nsec > 0)
{
td->tv_nsec -= NS_PER_SECOND;
td->tv_sec++;
}
}
int main(void)
{
struct timespec start, finish, delta;
clock_gettime(CLOCK_REALTIME, &start);
sleep(1);
clock_gettime(CLOCK_REALTIME, &finish);
sub_timespec(start, finish, &delta);
printf("%d.%.9ld\n", (int)delta.tv_sec, delta.tv_nsec);
return 0;
}
При запуске (как cgt61
) я получаю такие результаты:
$ cgt61
1.004930000
$ cgt61
1.004625000
$ cgt61
1.003023000
$ cgt61
1.003343000
$
Это было проверено на Mac;Вы можете видеть, что последние три цифры всегда нули.В виртуальной машине Linux (Ubuntu 18.04 на Mac) мне пришлось добавить #define _POSIX_C_SOURCE 200809L
в код (потому что я компилирую с -std=c11
; если бы я использовал -std=gnu11
, у меня все было бы в порядке), и вывод был:
$ ./cgt61
1.000589528
$