一帮情况可以使用Sleep()函数来实现延时,但Windows不是实时的,是操作系统来分配处理器给多个线程的,而不会线程一直拥有处理器的使用权。比如延时50ms,不论采用什么方式来延时,50ms以后,操作系统未必就正好把处理器分配给这个线程使用。
使用一个Sleep(50),这下这个线程就暂停了,50ms以内操作系统就不会把处理器给这个线程用,50ms以后这个线程要求处理器,操作系统才会可能给他分配,但是仅仅是可能,也有可能这时候有一个优先级更高的线程也要用处理器,操作系统就不一定给他。可能等到这个更高优先级的线程用完了,这时候已经过了55ms了,就不是精确的了。
在Windows平台下,常用的计时器还有另外两种,一种是timeGetTime多媒体计时器,它可以提供毫秒级的计时。但这个精度对很多应用场合而言还是太粗糙了。另一种是QueryPerformanceCount计数器,随系统的不同可以提供微秒级的计数。对于实时图形处理、多媒体数据流处理、或者实时系统构造的程序员,善用QueryPerformanceCount/QueryPerformanceFrequency是一项基本功。
可以使用 QueryPerformanceCount/QueryPerformanceFrequency实现微秒级的延时,例子如下:
void DelayUs(double uDelay)
{
LARGE_INTEGER litmp;
LONGLONG QPart1,QPart2;
double dfMinus,dfFreq,dfTim; //定义变量
/*
Pointer to a variable that the function sets, in counts per second, to the current performance-counter frequency.
If the installed hardware does not support a high-resolution performance counter,
the value passed back through this pointer can be zero.
*/
QueryPerformanceFrequency(&litmp); //获取当前电脑的时钟频率
dfFreq = (double)litmp.QuadPart;
/*
Pointer to a variable that the function sets, in counts, to the current performance-counter value.
*/
QueryPerformanceCounter(&litmp); //获取延时前的CPU执行次数
QPart1 = litmp.QuadPart;
do
{
QueryPerformanceCounter(&litmp);//获取延时后的CPU执行次数
QPart2 = litmp.QuadPart;
dfMinus = (double)(QPart2-QPart1);//延时后的CPU执行次数 减去 延时前的CPU执行次数
if (dfMinus < 0)
break;
dfTim = dfMinus/dfFreq * 1000000;
//dfTim = dfMinus/dfFreq;
}while(dfTim< uDelay); //延时时间小于预定值,继续进行延时
}
对延时函数进行测试:
#include <stdio.h>
#include <Windows.h>
void DelayUs(double uDelay)
{
LARGE_INTEGER litmp;
LONGLONG QPart1,QPart2;
double dfMinus,dfFreq,dfTim;
/*
Pointer to a variable that the function sets, in counts per second, to the current performance-counter frequency.
If the installed hardware does not support a high-resolution performance counter,
the value passed back through this pointer can be zero.
*/
QueryPerformanceFrequency(&litmp);
dfFreq = (double)litmp.QuadPart;
/*
Pointer to a variable that the function sets, in counts, to the current performance-counter value.
*/
QueryPerformanceCounter(&litmp);
QPart1 = litmp.QuadPart;
do
{
QueryPerformanceCounter(&litmp);
QPart2 = litmp.QuadPart;
dfMinus = (double)(QPart2-QPart1);
if (dfMinus < 0)
break;
dfTim = dfMinus/dfFreq * 1000000;
//dfTim = dfMinus/dfFreq;
}while(dfTim< uDelay);
}
void main()
{
LARGE_INTEGER t1, t2, tc;
QueryPerformanceFrequency(&tc);
printf("Frequency: %u \n", tc.QuadPart);
QueryPerformanceCounter(&t1);
//Sleep(1000);
DelayUs(20000);
QueryPerformanceCounter(&t2);
printf("Begin Time: %u \n", t1.QuadPart);
printf("End Time: %u \n", t2.QuadPart);
printf("Lasting Time: %u \n",( t2.QuadPart- t1.QuadPart));
}
程序执行结果:
机器的CPU频率为3117382Hz
延时前CPU执行次数为:985262162
延时后CPU执行次数为:985324514
延时函数总共耗费CPU执行次数为:62352
实际延时时间为:62352/3117382 ≈0.02000139860947423190356523518773
延时误差在0.2微秒以内,基本能达到微秒级的延时要求。