[转]C++获取Windows时间的方法总结

摘要:
现在总结Windows下的几个常用时间函数。睡眠功能不起计时的作用,而主要起延迟的作用。精度:Windows NT 3.5及更高版本的精度为10ms。它的时间精度高于时钟功能。GetTickCount()常用于多媒体。但是,与GetTickCount相比,timeGetTime可以通过timeBeginPeriod和timeEndPeriod设置计时器的最小分辨率精度。TimeBeginPeriod和timeEndPeriod必须成对出现。

     我们在衡量一个函数运行时间、判断一个算法的时间效率、在程序中我们需要一个定时器,定时执行一个特定的操作(比如在多媒体中、在游戏中等都会用到时间函数)、我们通过记录函数或者算法开始和截至的时间,然后利用两者之差得出函数或者算法的运行时间。编译器和操作系统为我们提供了很多时间函数,这些时间函数的精度也是各不相同的,如果我们想得到准确的结果,必须使用合适的时间函数。现在总结下Windows下的几种常用时间函数。

1:Sleep函数

    使用:sleep(1000),在Windows和Linux下1000代表的含义并不相同,Windows下的表示1000毫秒,也就是1秒钟;Linux下表示1000秒,Linux下使用毫秒级别的函数可以使用usleep。

    原理:sleep函数是使调用sleep函数的线程休眠,线程主动放弃时间片。当经过指定的时间间隔后,再启动线程,继续执行代码。Sleep函数并不能起到定时的作用,主要作用是延时。在一些多线程中可能会看到sleep(0);其主要目的是让出时间片。

    精度:sleep函数的精度非常低,当系统越忙它精度也就越低,有时候我们休眠1秒,可能3秒后才能继续执行。它的精度取决于线程自身优先级、其他线程的优先级,以及线程的数量等因素。

2:MFC下的timer事件

    使用:1.调用函数SetTimer()设置定时间隔,如SetTimer(0,100,NULL)即为设置100毫秒的时间间隔;2.在应用程序中增加定时响应函数OnTimer(),并在该函数中添加响应的处理语句,用来完成时间到时间的操作。

    原理:同sleep函数一样。不同的是timer是一个定时器,可以指定回调函数,默认为OnTimer()函数。

    精度:timer事件的精度范围在毫米级别,系统越忙其精度也就越差。

3:C语言下的Time

    使用:time_t t;time(&t);Time函数是获取当前时间。

        time_t t1;

        tm *tp1;

        t1=time(NULL);

        tp1=localtime(&t1);

        printf("%d/%d/%d\n",tp->tm_mon+1,tp->tm_mday,tp->tm_year+1900);

        printf("%d:%d:%d\n",tp1->tm_hour,tp1->tm_min,tp1->tm_sec);

    原理:time函数主要用于获取当前时间,比如我们做一个电子时钟程序,就可以使用此函数,获取系统当前的时间。

    精度:秒级别。

4:COM对象中的COleDateTime,COleDateTimeSpan类

    使用:

        COleDateTime start_time = COleDateTime::GetCurrentTime();

        COleDateTimeSpan end_time = COleDateTime::GetCurrentTime()-start_time;

        While(end_time.GetTotalSeconds() < 2)

        {

        // 处理延时或定时期间能处理其他的消息

        DoSomething()

        end_time = COleDateTime::GetCurrentTime-start_time;

        }

    原理:以上代表延时2秒,而这两秒内我们可以循环调用DoSomething(),从而实现在延时的时候我们也能够处理其他的函数,或者消息。COleDateTime,COleDateTimeSpan是MFC中CTime,CTimeSpan在COM中的应用,所以,上面的方法对于CTime,CTimeSpa同样有效。

    精度:秒级别。

5:C语言下的时钟周期clock()

    使用:

        clock_t start = clock();

        Sleep(100);

        clock_t end = clock();

        double d = (double)(start - end) / CLOCKS_PER_SEC;

    原理:clock()是获取计算机启动后的时间间隔。

    精度:ms级别,对于短时间内的定时或者延时可以达到ms级别,对于时间比较长的定时或者延迟精度还是不够。在windows下CLOCKS_PER_SEC为1000。

6:Windows下的GetTickCount()

    使用:

        DWORD start = GetTickCount();

        Sleep(100);

        DWORD end = GetTickCount();

    原理:GetTickCount()是获取系统启动后的时间间隔。通过进入函数开始定时,到退出函数结束定时,从而可以判断出函数的执行时间,这种时间也并非是函数或者算法的真实执行时间,因为在函数和算法线程不可能一直占用CPU,对于所有判断执行时间的函数都是一样,不过基本上已经很准确,可以通过查询进行定时。GetTickCount()和Clock()函数是向主板BIOS要real time clock时间,会有中断产生,以及延迟问题。

    精度:WindowsNT 3.5以及以后版本精度是10ms,它的时间精度比clock函数的要高,GetTickCount()常用于多媒体中。

7:Windows下timeGetTime

    使用:需要包含Mmsystem.h,Windows.h,加入静态库Winmm.lib.

        timeBeginPeriod(1);

        DWORD start = timeGetTime();

        Sleep(100);

        DWORD end = timeGetTime();

        timeEndPeriod(1);

    原理:timeGetTime也时常用于多媒体定时器中,可以通过查询进行定时。通过查询进行定时,本身也会影响定时器的定时精度。

    精度:毫秒,与GetTickCount()相当。但是和GetTickCount相比,timeGetTime可以通过timeBeginPeriod,timeEndPeriod设置定时器的最小解析精度,timeBeginPeriod,timeEndPeriod必须成对出现。

8:Windows下的timeSetEvent

    使用:还记的VC下的Timer吗?Timer是一个定时器,而以上我们提到几种时间函数或者类型,实现定时功能只能通过轮训来实现,也就是必须另外创建一个线程单独处理,这样会影响定时精度,好在windows提供了内置的定时器timeSetEvent,函数原型为

MMRESULT timeSetEvent( UINT uDelay, //以毫秒指定事件的周期

        UINT uResolution, //以毫秒指定延时的精度,数值越小定时器事件分辨率越高。缺省值为1ms

        LPTIMECALLBACK lpTimeProc, //指向一个回调函数

        WORD dwUser, //存放用户提供的回调数据

        UINT fuEvent )// 标志参数,TIME_ONESHOT:执行一次;TIME_PERIODIC:周期性执行

具体应用时,可以通过调用timeSetEvent()函数,将需要周期性执行的任务定义在 lpFunction回调函数中(如:定时采样、控制等),从而完成所需处理的事件。需要注意的是:任务处理的时间不能大于周期间隔时间。另外,在定时器使用完毕后,应及时调用timeKillEvent()将之释放。

    原理:可以理解为代回调函数的timeGetTime

    精度:毫秒,timeSetEvent可以通过timeBeginPeriod,timeEndPeriod设置定时器的最小解析精度, timeBeginPeriod,timeEndPeriod必须成对出现。

9:高精度时控函数QueryPerformanceFrequency,QueryPerformanceCounter

    使用:

        LARGE_INTEGER m_nFreq;

        LARGE_INTEGER m_nBeginTime;

        LARGE_INTEGER nEndTime;

        QueryPerformanceFrequency(&m_nFreq); // 获取时钟周期

        QueryPerformanceCounter(&m_nBeginTime); // 获取时钟计数

        Sleep(100);

        QueryPerformanceCounter(&nEndTime);

        cout << (nEndTime.QuadPart-m_nBeginTime.QuadPart)*1000/m_nFreq.QuadPart << endl;

    原理:CPU上也有一个计数器,以机器的clock为单位,可以通过rdtsc读取,而不用中断,因此其精度与系统时间相当。

    精度:计算机获取硬件支持,精度比较高,可以通过它判断其他时间函数的精度范围。

10小结:

        以上提到常用的9种时间函数,由于他们的用处不同,所以他们的精度也不尽相同,所以如果简单的延时可以用sleep函数,稍微准确的延时可以使用clock函数,GetTickCount函数,更高级的实用 timeGetTime函数;简单的定时事件可以用Timer,准确地可以用timeSetEvent;或取一般系统时间可以通time,或者 CTime,或者COleDateTime,获取准确的时间可以用clock,或者GetTickCount函数,或者timeGetTime函数,而获取准确地系统时间要使用硬件支持的QueryPerformanceFrequency函数,QueryPerformanceCounter函数。

免责声明:文章转载自《[转]C++获取Windows时间的方法总结》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇leetcode691:Stickers to Spell Word华为机试 计算字符个数下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

51单片机串口通信的注记

最近折腾51单片机,当然学到的都是比较基础的东西,可能我认为比较复杂的概念有“中断” 和“串口通信”,这篇主要是讲串口通信 使用的自然是山大王STC89C52RC的芯片来学习 串口通信主要是C51单片机的RXD 和TXD 与上位机进行通信,由于上位机一般是电脑,所以要TTL转成电脑能读出的RS232的电路来支持   一般使用MAX232 芯片   串口通信...

c#定时器Timer

C# Timer用法有哪些呢?我们在使用C# Timer时都会有自己的一些总结,那么这里向你介绍3种方法,希望对你了解和学习C# Timer使用的方法有所帮助。 关于C# Timer类 在C#里关于定时器类就有3个 C# Timer使用的方法1.定义在System.Windows.Forms里 C# Timer使用的方法2.定义在System.Thread...

RTC硬件时钟设置修改【转】

转自:http://os.chinaunix.net/a2008/0526/981/000000981211.shtml 这两天一直在做i2c设备驱动的理解,所以很少更新文章。      由于对于表计来说,RTC硬件时钟是非常重要的,并且其精度设计要求是比较高的,在busybox中,可以通过date命令设置当前的系统时间,然后通过hwclock将当前的系统...

linux系统编程:自己动手写一个who命令

who命令的作用用于显示当前有哪些用户登录到系统。 这个命令执行的原理是读取了系统上utmp文件中记录的所有登录信息,直接显示出来的 utmp文件在哪里呢? man who的时候,在手册下面有这么一段说明:意思就是不指定文件参数,那么读取的就是/var/run/utmp,到底是不是,验证下 If FILE is not specified, use /va...

[RTOS]--uCOS、FreeRTOS、RTThread、RTX等RTOS的对比之特点

本篇博客就来细数这几个RTOS的特点。   以下内容均来自官方网站或者官方手册Feature的Google翻译的加了我的一些调整,没有任何主观成分。 1. FreeRTOS   FreeRTOS是专为小型嵌入式系统设计的可扩展的实时内核。 亮点包括: 微小的封装形式。 免费的RTOS调度程序 免费嵌入式软件源代码。 免版税。 抢占式,协作式和混合配置...

用Visual C++制作微秒级精度定时器

在工业生产控制系统中,有许多需要定时完成的操作,如:定时显示当前时间,定时刷新屏幕上的进度条,上位机定时向下位机发送命令和传送数据等。特别是在对控制性能要求较高的控制系统和数据采集系统中,就更需要精确定时操作。众所周知,Windows是基于消息机制的系统,任何事件的执行都是通过发送和接收消息来完成的。这样就带来了一些问题,如一旦计算机的CPU被某个进程占用...