Winapi 用于Windows XP的线程安全GetTickCount64实现

Winapi 用于Windows XP的线程安全GetTickCount64实现,winapi,Winapi,我的目标是Windows XP,我需要一个类似于GetTickCount64的函数,它不会溢出 我找不到一个合适的、正确的、线程安全的解决方案,所以我试着推出自己的解决方案 以下是我的想法: ULONGLONG MyGetTickCount64(void) { static volatile DWORD dwHigh = 0; static volatile DWORD dwLastLow = 0; DWORD dwTickCount; dwTickCount

我的目标是Windows XP,我需要一个类似于GetTickCount64的函数,它不会溢出

我找不到一个合适的、正确的、线程安全的解决方案,所以我试着推出自己的解决方案

以下是我的想法:

ULONGLONG MyGetTickCount64(void)
{
    static volatile DWORD dwHigh = 0;
    static volatile DWORD dwLastLow = 0;
    DWORD dwTickCount;

    dwTickCount = GetTickCount();
    if(dwTickCount < (DWORD)InterlockedExchange(&dwLastLow, dwTickCount))
    {
        InterlockedIncrement(&dwHigh);
    }

    return (ULONGLONG)dwTickCount | (ULONGLONG)dwHigh << 32;
}
ULONGLONG MyGetTickCount64(无效)
{
静态易失性DWORD dwHigh=0;
静态易失性DWORD dwLastLow=0;
德沃德·德维克;
dwTickCount=GetTickCount();
if(dwTickCount<(DWORD)联锁交换(&dwLastLow,dwTickCount))
{
联锁增量(&dwHigh);
}

在Windows上返回(ULONGLONG)dwTickCount |(ULONGLONG)dwHigh在游戏中,通常使用
QueryPerformanceCounter()
函数而不是
GetTickCount()
来解决计时器溢出问题:


您还可以签出完整的源代码(可在Windows和许多其他平台之间移植)来自我们的开源Linderdaum引擎:

不,这不是线程安全的。它甚至不正确。您对
InterlockedIncrement
的调用充其量只是一种猜测。您似乎还使用
volatile
来表示其他含义:。谢谢您的评论。我想我还没有学到一两件关于无锁编程的事情。W呃,我试过:)事实上,我用另一种方式解决了我的问题……什么都不做:)在计算两个GetTickCount结果之间的差异时,49天的溢出并不会真正破坏结果(除非时间差那么大)。谢谢您的回答。它完美地回答了我的问题,因此我将其标记为已接受,尽管我找到了另一个解决方案:因为我只计算时间差,结果表明49天的溢出不是问题。
QueryPerformanceCounter()
的分辨率比
GetTickCount()高得多
,最长可达纳秒。
double GetCycles() const
{
    LARGE_INTEGER T1;
    QueryPerformanceCounter( &T1 );
    return static_cast<double>( T1.QuadPart );
}
void Initialize()
{
    LARGE_INTEGER Freq;
    QueryPerformanceFrequency( &Freq );
    double CyclesPerSecond = static_cast<double>( Freq.QuadPart );
    RecipCyclesPerSecond = 1.0 / CyclesPerSecond;
}
double GetSeconds() const
{
    return GetCycles() * RecipCyclesPerSecond;
}