65.9K
CodeProject 正在变化。 阅读更多。
Home

计时器和时间

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.77/5 (7投票s)

2004年4月1日

2分钟阅读

viewsIcon

64520

downloadIcon

4619

制作定时事件标志、函数、线程及其计时。

引言

这个 DLL 提供了十五个例程,以满足 C/C++ 和 VB 环境中定时器和定时活动的应用程序要求。 实践表明,150 个定时器槽对于任何应用程序来说都足够了。 每个定时器都可以设置为引发事件标志、执行函数(在计时器线程上)或启动一个线程。 定时器在创建时被分配一个编号(例如,1 到 150)。 可以通过定时器编号取消或修改定时器。

背景

在初始化时,会启动两个线程。 计时器线程每毫秒触发一次,使用 winmm.dll,Windows (R) 多媒体库(该库包含精确到一毫秒的调用)。 该线程的每次执行都会递减正值定时器。 当定时器达到零时,其动作(三种之一)被执行,并且定时器过期(负状态)。 计时器线程用于执行定时器过期时要调用的函数,并在需要时退出两个线程,计时器线程和计时器线程。 此计时器线程可能会过载,因为它必须完成一个函数才能开始另一个函数。 在这种情况下,请使用 make_tmrT 而不是 make_tmrF。 初始化是在对任何定时器或计时例程的第一次调用时完成的。

使用代码

VC 6.0 项目:将 TIMDLL.dll 放在您的路径变量中的一个目录中。 将库 TIMDLL.lib 添加到项目资源中。 将模块 TIMcalls.h 添加到项目中。 使用其中的例程。

VB 6.0 项目:使用 regsvr32 注册 TIMDLL.dll。 将模块 TIMDLL.bas 添加到项目中。 使用其中的公共例程。

//
// Source to produce the above console screen
//
#include "TIMcalls.h"
#include "stdio.h"// for printf
static bool pM = true; long timer_id[]= {0,0,0,0};
//
// 'cbr' is a 13sec repeating function, called by the 'ticker' thread
//
void cbr (void*prm) {printf("\nFunction cbr  fires, 
  ictr %5d, prm %d",TIM_ictr(),(long)prm);}
//
// 'one' is a one-shot function, called by the 'ticker' thread, which
// calls itself on 5sec boundaries while TIM_ictr < 30 seconds
//
void one (void*prm)
{
  printf("\nFunction one  fires, ictr %5d, prm %d",TIM_ictr(),(long)prm);
  if (TIM_ictr() < 30000)
  {
    TIM_make_tmrF(5000-(TIM_ictr()%5000),&timer_id[2],
      one,(void*)(TIM_ictr()/1000),false);

    if (timer_id[0] > 0 && TIM_mod_tmr(timer_id[0],
            20000-TIM_ictr()) != TIM_SUCCESS)
       timer_id[0] = 0;//make_tmr has expired, clear ID

    printf("\nIDs %d,%d,%d,%d",timer_id[0],
      timer_id[1],timer_id[2],timer_id[3]);
  }
}
//
// 'thr' is an 18sec repeating thread, 
// spun by 'ticker-ticker' thread
//
void thr (void*prm) {printf("\nThread   thr  fires, ictr %5d, prm %d",
   TIM_ictr(),(long)prm);}
//
//
//
void main (int argc, char*argv[])
{
  HANDLE flg_han; unsigned long sts;
    
  TIM_make_tmr (20000,&timer_id[0],"",false);
  TIM_make_tmrF(13000,&timer_id[1],cbr,(void*)123,true);
  TIM_make_tmrF(11000,&timer_id[2],one,(void*)456,false);
  TIM_make_tmrT(18000,&timer_id[3],thr,(void*)789,true);

  flg_han = TIM_get_handle(timer_id[0]);

  printf("\nIDs %d,%d,%d,%d",timer_id[0],
      timer_id[1],timer_id[2],timer_id[3]);

  while(pM)
  {
    Sleep(1000-(TIM_ictr()%1000));// next second boundary

    sts = WaitForSingleObject(flg_han,0);// check for flag set

    if (sts != WAIT_OBJECT_0)
    printf("\nFlag    not yet set, ictr %5d",TIM_ictr());
    else{printf("\nFlag            set, ictr %5d",TIM_ictr()); pM=false;}
  }

  Sleep(57000-TIM_ictr());// 57second boundary

  printf("\nAbout to reset TIM sub-system");
  long ictr = TIM_ictr();
  TIM_reset();
  printf("\n  ...TIM_reset, about to exit");

  Sleep(80000-ictr);// 80second boundary (i.e.23secs) to read the screen
}

关注点

对于仅使用 C/C++ 的用户,可以使用工作区和提供的项目文件构建静态库。 由事件标志设置定时器使用的槽在绝对必要之前不会被重用,因此句柄可用,并且可以在过期后查询标志状态。 更精确的第二个演示 VB 项目使用 ccrpTmr.dll。 使用 regsvr32 注册 ccrpTmr.dll(“通用控件替换项目”DLL,免费提供于 ccrp.mvps.org)。

历史

  • 3.4 TIM_Src.cpp - 注释/日志维护。
© . All rights reserved.