Получите метку времени в микросекундах в c с максимальным переменным размером 32 бита - PullRequest
0 голосов
/ 09 июля 2019

Мне нужно получить метку времени с разрешением в микросекунды. Я нашел варианты, такие как использование временной структуры и вызов gettimeofday. Проблема в том, что все структуры содержат длинные переменные, и я могу работать только с 32-битными переменными.

Как я могу получить метку времени (в c), используя только 32-битные переменные?

Ответы [ 2 ]

1 голос
/ 09 июля 2019

Этот сайт является очень хорошим справочным материалом для программирования времени и часов в целом, включая прототипы функций, определения структур, а также примеры программирования, которые соответствуют вашему запросу. Вы должны взглянуть.

Есть несколько ответов из здесь , которые могут быть адаптированы к тому, что вам нужно. Принятый ответ является общим:

Для 32-битных систем:

fprintf(stdout, "%u\n", (unsigned)time(NULL)); )_

Этот ответ на тот же вопрос , в частности, касается разрешения США. Однако это зависит от POSIX и может нарушать ваши спецификации. :

#include <stdio.h>
#include <time.h>
#include <stdint.h>
#include <inttypes.h>
int main(void) {

    struct timespec tms;

    /* The C11 way */
    /* if (! timespec_get(&tms, TIME_UTC)) { */

    /* POSIX.1-2008 way */
    if (clock_gettime(CLOCK_REALTIME,&tms)) {
        return -1;
    }
    /* seconds, multiplied with 1 million */
    int64_t micros = tms.tv_sec * 1000000;
    /* Add full microseconds */
    micros += tms.tv_nsec/1000;
    /* round up if necessary */
    if (tms.tv_nsec % 1000 >= 500) {
        ++micros;
    }
    printf("Microseconds: %"PRId64"\n",micros);
    return 0;
}
0 голосов
/ 10 июля 2019

Если поля struct timeval имеют long целочисленный формат (который может быть или не быть) в 32-битном формате, , потому что вам нужно, чтобы он был такого размера. Давайте проведем некоторый анализ: я взялэта временная метка в формате NTP и преобразована в формат struct timeval (для сейчас отметка времени) в моей системе:

ntpts.c:120:process:  NTP(dec): 3771731346.612550000
ntpts.c:121:process:  NTP(hex): 0xe0d00d92.9cd013a9
ntpts.c:123:process:      UNIX: 1562742546/0x5d258f12
ntpts.c:135:process:    gmtime: 10/jul/2019, 07:09:06.612550000
ntpts.c:136:process: localtime: 10/jul/2019, 10:09:06.612550000

tv_sec  ==> 1562742546
tv_usec ==>     612550

, чтобы получить одну отметку времени с этим разрешением (числосекунд с 00:00 часов января / 1/1970 и микросекунд) вам нужно как минимум 52 бита (ну, обычно tv_sec - это поле long или long long 64 бита, из-за переполнения, которое произойдетв Феве, 2038, и некоторые системы уже исправили это), и tv_usec может быть помещен в 24-битную переменную (usec идет от 0 до 999999, поэтому им нужно по крайней мере 20 бит), но заполнение компилятора сделает его 32-битным в любом случае, как минимум.

В случае, если вы хотите сохранить полное разрешение usec с 32 битами, вам потребуется не менее 20 бит для представления доли секунды, и у вас будет только 12 бит для представления целого числачасть.В этом случае вы сможете выразить только секунды от 0 до 4095, что составляет более одного часа (01h8m16s).Это возможно, но чтобы сделать эту временную метку абсолютной, вам нужно указать, к какому абсолютному часу в истории относится эта временная метка.

С другой стороны, если вы уменьшите гранулярность до мс, вы можетечтобы получить более 1000 часов контрольного окна, вам необходимо учесть это, чтобы окончательно решить, что делать дальше.

AMENDMENT

Кстати, системный вызов gettimeofday(2) фактически устарел.Почти все системы, используемые в настоящее время, используют системный вызов clock_gettime(2), который имеет разрешение наносекунд и позволяет вам выбрать правильные системные часы для получения метки времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...