window計時不準導致的bug

近來發現sleep(20)不精確,導致播放器播放速度有問題。


於是用以下方法測試:

分別用WaitForSingleObject + GetTickCount,

WaitForSingleObject +  QueryPerformance, 

Sleep + GetTickCount,

Sleep  +  QueryPerformance, 來打印延時計數,

試了n次後發現,得出以下結論:windows系統(至少我的電腦上),

1、不管用sleep還是waitforsingleobject,掛起的延時都是時準時不準,不穩定

2、GetTickCount計時以15ms(左右)作爲一個基本單位的。最好用QueryPerformance代替。

以下是測試代碼

void gwsleep1(DWORD iMilliseconds)
{
static HANDLE xevent = CreateEvent(NULL, TRUE, FALSE, NULL);



LARGE_INTEGER startCount;
LARGE_INTEGER endCount;
LARGE_INTEGER freq;


QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&startCount);
Sleep(iMilliseconds);
QueryPerformanceCounter(&endCount);
double elapsed = (double)(endCount.QuadPart - startCount.QuadPart) / freq.QuadPart;
ATLTRACE(_T("\n sleep+Query:%f"), elapsed);




QueryPerformanceCounter(&startCount);
WaitForSingleObject(xevent, iMilliseconds);
QueryPerformanceCounter(&endCount);
elapsed = (double)(endCount.QuadPart - startCount.QuadPart) / freq.QuadPart;
ATLTRACE(_T("\n wait+Query:%f"), elapsed);
}




void gwsleep2(DWORD iMilliseconds)
{
static HANDLE xevent = CreateEvent(NULL, TRUE, FALSE, NULL);


DWORD t1, t2;
t1 = GetTickCount();
Sleep(iMilliseconds);
t2 = GetTickCount();
DWORD elapsed2 = t2 - t1;
ATLTRACE(_T("\n sleep+ticount:%d"), elapsed2);




t1 = GetTickCount();
WaitForSingleObject(xevent, iMilliseconds);
t2 = GetTickCount();
elapsed2 = t2 - t1;
ATLTRACE(_T("\n wait+ticount:%d"), elapsed2);
}






void CsleeptestDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知處理程序代碼
for (int i=1; i<100; i++)
{
ATLTRACE(_T("\n\n ******************************************************"));
ATLTRACE(_T("\n %d "), i);
ATLTRACE(_T("\n\n ******************************************************"));


int iMaxCount = 1;
int iCurrCount = 0;
while (iCurrCount < iMaxCount)
{
gwsleep1(i);
gwsleep2(i);
ATLTRACE(_T("\n ======================================================== "));
iCurrCount ++;
}
}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章