GetTickCount和Sleep

来源:http://blog.sina.com.cn/s/blog_6235f42c0100i6n7.html

GetTickCount返回(retrieve)从操作系统启动到现在所经过(elapsed)的毫秒数,它的返回值是DWORDGetTickCount函数的原型为

DWORD GetTickCount(void);

它在winbase.h头文件中定义为

WINBASEAPI

DWORD

WINAPI

GetTickCount(

    VOID

    );

winbase.h已被包含进windows.h头文件中,所以要使用GetTickCount只需包含windows.h就可以了。

用一个DWORD类型的值存放一个时间数值,那么经历足够长的时间,这个数值一定会溢出绕回到零(wrap around to zero),我们可以计算这个时间。先算一下一天有多少毫秒mmsEachDay = 24*60*60*1000=86,400,000ms。而一个DWORD最大能表示多达数值呢?DWORD在头文件windef.h中定义如下
typedef unsigned long DWORD; 
可以看出DWORD是一个占四个字节即两个字的空间无符号整数,它能表示的最大值为232=4,294,967,695,而4,294,967,695/86,400,000 = 49.71,所以若系统持续运行(run continuously)49.71天,这个数会溢出绕回到零。
可以使用GetTickCount()来大概确定一段代码执行了多少时间,例程如下:

#i nclude <windows.h>

    #i nclude <stdio.h>

    //……..

    DWORD dwStart;

    DWORD dwEnd;

    dwStart = GetTickCount();

    printf( "dwStart:%d\n", dwStart );

    //YOUR CODE TO BE TIMED;

    dwEnd = GetTickCount();

    printf( "dwEnd:%d\n", dwEnd );

    printf( "elapsed:%d\n", dwEnd dwStart )

 

也可以用GetTickCount函数来进行定时,比如若要定时1s,可以使用如下代码:

#i nclude <windows.h>

#i nclude <stdio.h>

void main()

{

     DWORD dwLast;

     DWORD dwCurrent;

     DWORD dwInterval = 1000;

 

dwLast = GetTickCount();

     int i = 0;

     while(true)

     {

         dwCurrent = GetTickCount();

         if( dwCurrent - dwLast < dwInterval )

              continue;

         //your code to be executed when interval is elapsed

         printf("dwLast,dwCurrent,diff:%d,%d,%d\n",dwLast,dwCurrent,dwCurrent-dwLast);

         //your code to determine when to break

         if( i > 10 ) break;

         i++;

         dwLast = dwCurrent;

     }

   getchar();  

   return;

}

 

GetTickCount的分辨率是1ms。在精度要求不高的情况下也可以使用Sleep()函数定时,它的最小分辨率大概是55ms,Sleep的函数原型为
void Sleep( DWORD dwMilliseconds );
Sleep在winbase.h中的定义如下

WINBASEAPI

VOID

WINAPI

Sleep(

    IN DWORD dwMilliseconds

    );

其中VOID是基本数据类型void的别名,可以参见winnt.h中的定义

#ifndef VOID

#define VOID void

typedef char CHAR;

typedef short SHORT;

typedef long LONG;

#endif

如果要使用更高分辨率的话请使用多媒体定时器(multimedia timer)或高分辨率定时器(high-resolution timer)。
GetTickCount在.NET Framework中有一个对应项(counterpart)即System.Environment.TickCount属性。TickCount属性在Environment类中定义如下
public static int TickCount {get;} 
System.Environment.TickCount属性的值从系统计时器派生,并以 32 位有符号整数的形式存储。因此,如果系统连续运行 24.9 天,则运行时间将四舍五入到零位。TickCount 属性通过将其值重置为零来处理溢出状况。TickCount 返回的最小值为 0。MSDN上说TickCount 属性的分辨率不能小于 500 毫秒。我在程序中测试可以看出TickCount 的分辨率大概为15~16ms。测试代码如下[C#]

using System;

namespace ConsoleApplication2

{

     /// <summary>

     /// Class1 的摘要说明。

     /// </summary>

     class Class1

     {

         /// <summary>

         /// 应用程序的主入口点。

         /// </summary>

         [STAThread]

         static void Main(string[] args)

         {

              // TODO: 在此处添加代码以启动应用程序

              for(int i=0;i<100;i++)

              {

                   Console.WriteLine(i.ToString());

                   Console.WriteLine("start TickCount:" + System.Environment.TickCount.ToString());

                   System.Threading.Thread.Sleep(1);                 

                   Console.WriteLine("1ms elapsed TickCount:" + System.Environment.TickCount.ToString());

              }

              //pause for checking

              System.Console.ReadLine();

         }

     }

}

结果的一部分为(当然,多次执行得到的结果不同,但规律相同):

start TickCount:84

 

 

 在要求误差不大于1毫秒的情况下,可以采用GetTickCount()函数,该函数的返回值是DWORD型,表示以毫秒为单位的计算机启动后经历的时间间隔。使用下面的编程语句,可以实现50毫秒的精确定时,其误差小于1毫秒。    
   
    DWORD   dwStart,   dwStop;    
   
    //   起始值和终止值    
   
    dwStop   =   GetTickCount();    
   
    while(TRUE)    
   
    {    
   
       dwStart   =   dwStop;    
   
    //   上一次的终止值变成新的起始值    
   
    //   此处添加相应控制语句    
   
       do    
   
       {    
   
    dwStop   =   GetTickCount();    
   
       }   while(dwStop   -   50   <   dwStart);    
   
    } 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
仔细分析下列代码的优缺点:#include <stdio.h> #include <stdlib.h> #include <windows.h> #define N 5 #define LEFT (i + N - 1) % N #define RIGHT (i + 1) % N #define THINKING 0 #define HUNGRY 1 #define EATING 2 #define TIMEOUT 1000 int state[N]; // 每个哲学家的状态 HANDLE mutex; // 互斥锁 HANDLE s[N]; // 条件变量 void test(int i) { if (state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT] != EATING) { state[i] = EATING; printf("哲学家 %d 拿到筷子开始进餐\n", i); ReleaseSemaphore(s[i], 1, NULL); } } void pickup(int i) { DWORD start_time = GetTickCount(); while (1) { WaitForSingleObject(mutex, INFINITE); state[i] = HUNGRY; printf("哲学家 %d 饥饿了,开始思考和拿起左手边的筷子\n", i); test(i); ReleaseMutex(mutex); WaitForSingleObject(s[i], TIMEOUT); WaitForSingleObject(mutex, INFINITE); if (state[i] == EATING) { ReleaseMutex(mutex); break; } else { state[i] = THINKING; printf("哲学家 %d 没有拿到两根筷子,放下筷子并等待一段时间后重新开始尝试\n", i); ReleaseMutex(mutex); Sleep(rand() % 5000 + 1000); } if (GetTickCount() - start_time > TIMEOUT) { printf("哲学家 %d 超时,放弃进餐\n", i); return; } } } void putdown(int i) { WaitForSingleObject(mutex, INFINITE); state[i] = THINKING; printf("哲学家 %d 放下筷子,开始思考\n", i); test(LEFT); test(RIGHT); ReleaseMutex(mutex); } DWORD WINAPI philosopher(LPVOID lpParam) { int i = (int)lpParam; while (1) { Sleep(rand() % 5000 + 1000); // 思考一段时间 pickup(i); Sleep(rand() % 5000 + 1000); // 进餐一段时间 putdown(i); } return 0; } int main() { int i; HANDLE thread[N]; srand(GetTickCount()); mutex = CreateMutex(NULL, FALSE, NULL); for (i = 0; i < N; i++) { s[i] = CreateSemaphore(NULL, 0, 1, NULL); state[i] = THINKING; } for (i = 0; i < N; i++) { thread[i] = CreateThread(NULL, 0, phi
06-07

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值