Winapi 用于Windows XP的线程安全GetTickCount64实现
我的目标是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
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;
}