近来发现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 ++;
}
}
}