c - 在 Windows 上使用 gettimeofday() 等价物

标签 c windows time

我正在尝试使用 Visual Studio 2013 在 Windows 上为 UNIX 的 gettimeofday() 函数使用 2 个不同的等价物。

我从here中拿了第一个.作为第二个,我正在使用 _ftime64_s 函数,如 here 所解释的那样.

它们有效,但不如我预期。我想在打印秒数或至少毫秒数时获得不同的值,但我使用 gettimeofday()(mytime1 和 mytime2)和 _ftime64_s(mytime3 和 mytime4)获得相同的打印值。

不过值得一提的是,这两个函数的毫秒值确实不同(即mytime1/mytime2和mytime3/mytime4的毫秒值不同)。

这是我的代码:

#include <stdio.h>
#include <Windows.h>
#include <stdint.h>
#include <sys/timeb.h>
#include <time.h>

#define WIN32_LEAN_AND_MEAN

int gettimeofday(struct timeval * tp, struct timezone * tzp)
{
    // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
    static const uint64_t EPOCH = ((uint64_t)116444736000000000ULL);

    SYSTEMTIME  system_time;
    FILETIME    file_time;
    uint64_t    time;

    GetSystemTime(&system_time);
    SystemTimeToFileTime(&system_time, &file_time);
    time = ((uint64_t)file_time.dwLowDateTime);
    time += ((uint64_t)file_time.dwHighDateTime) << 32;

    tp->tv_sec = (long)((time - EPOCH) / 10000000L);
    tp->tv_usec = (long)(system_time.wMilliseconds * 1000);
    return 0;
}

int main()
{
    /* working with struct timeval and gettimeofday equivalent */

    struct timeval mytime1;
    struct timeval mytime2;

    gettimeofday(&(mytime1), NULL);
    gettimeofday(&(mytime2), NULL);

    printf("Seconds: %d\n", (int)(mytime1.tv_sec));
    printf("Milliseconds: %d\n", (int)(mytime1.tv_usec));

    printf("Seconds: %d\n", (int)(mytime2.tv_sec));
    printf("Milliseconds: %d\n", (int)(mytime2.tv_usec));

    /* working with _ftime64_s */

    struct _timeb mytime3;
    struct _timeb mytime4;

    _ftime64_s(&mytime3);
    _ftime64_s(&mytime4);

    printf("Seconds: %d\n", mytime3.time);
    printf("Milliseconds: %d\n", mytime3.millitm);

    printf("Seconds: %d\n", mytime4.time);
    printf("Milliseconds: %d\n", mytime4.millitm);

    return (0);
}

我尝试了其他格式说明符(%f、%lu)和转换((float)、(double)、(long)、(size_t)),但没关系。欢迎提出建议。

最佳答案

QueryPerformanceCounter 用于在 windows 上进行精确计时。用法可以如下:

uint64_t microseconds()
{
    LARGE_INTEGER fq, t;
    QueryPerformanceFrequency(&fq);
    QueryPerformanceCounter(&t);
    return (1000000 * t.QuadPart) / fq.QuadPart;
}

据我所知,这不适用于任何 EPOCH。为此,您需要 GetSystemTimePreciseAsFileTime,它仅适用于 Windows 8 及更高版本。

uint64_t MyGetSystemTimePreciseAsFileTime()
{
    HMODULE lib = LoadLibraryW(L"kernel32.dll");
    if (!lib) return 0;
    FARPROC fp = GetProcAddress(lib, "GetSystemTimePreciseAsFileTime");
    ULARGE_INTEGER largeInt;
    largeInt.QuadPart = 0;
    if (fp)
    {
        T_GetSystemTimePreciseAsFileTime* pfn = (T_GetSystemTimePreciseAsFileTime*)fp;
        FILETIME fileTime = { 0 };
        pfn(&fileTime);
        largeInt.HighPart = fileTime.dwHighDateTime;
        largeInt.LowPart = fileTime.dwLowDateTime;
    }
    FreeLibrary(lib);
    return largeInt.QuadPart;
}

int main()
{
    uint64_t t1 = microseconds();
    uint64_t t2 = microseconds();
    printf("t1: %llu\n", t1);
    printf("t2: %llu\n", t2);
    return (0);
}

关于c - 在 Windows 上使用 gettimeofday() 等价物,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34831145/

相关文章:

c - 文件时间戳随文件资源管理器中的 SetFileTime() 消失

c - 微软怎么能说 WinAPI 中一个字的大小是 16 位呢?

c++ - 延迟加载 DLL

windows - 处理 Windows 命令中的扩展字符?

cArray[][] 指针数组转换

c - C 中的结构 *p != 地址

c - C 中的乘法问题

javascript - if 11pm 调用函数更改表单输入值

php - 从多个时间段创建连续的时间线

database - 如何在 PostgreSQL 中以毫秒为单位存储时间戳?