在DLL中使用定时器的问题

时间:2022-01-07 18:10:57

我在做MFC拓展库的时候,需要在DLL里用到定时器。本打算用OnTimer,因为没有窗口类,因此只能自己发消息。

方法就是:开一个线程在线程里调用SetTimer()并自己负责接收消息,然后在定时器回调函数里处理工作。

具体如下:

1 hThreadREC = (HWND)::CreateThread(NULL,0,ThreadRecordingState,NULL,0,NULL);
2 DWORD WINAPI ThreadRecordingState(LPVOID lpParameter)
  {

	SetTimer(NULL,NULL,1000,ThreadRecordingStateproc);

	MSG msg;
	while (GetMessage(&msg,NULL,0,0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return 0;
 }
3 VOID CALLBACK ThreadRecordingStateproc(HWND hWnd,UINT uMsg,UINT IdEvent,DWORD dwTime)
  {
         //...
  }

这样做不仅繁琐,而且多开几个线程不好同步。也可能dll里的消息发送会影响到主程序里的消息循环。

因此改用Sleep()。

即单开一个线程专用于计时,如下

DWORD WINAPI ThreadTime(LPVOID lpParameter)
{
   //根据不同功能用Sleep处理
   if()
   {
     sleep(100);
    }
    else if
    {
     Sleep(2000);
    }
    //...
   return 0;
}

但是,我是在初始化DLL是就开了这个线程,没有功能时就一直循环,会一直占用CPU,到此内存占用率变高。

此时有一种迫不得已的解决办法,即在return前加上sleep(1),即让线程去处理其它工作,虽然是1毫秒,但给了CPU喘息的机会

Sleep理解,摘自网络:

当调用Sleep函数的时候,比如Sleep(400);它告诉系统,此线程将放弃此次运行的时间片,比方说现在线程只执行了10ms,按“有关部门规定”它被唤醒一次
是要执行20ms的。这时它就说,这次机会我放弃,后面的10ms不要了。下次轮上我再叫我。 这样,系统便会将其终止,然后再一次进行调度选择。如果它运
气很好,又被选中了,系统则会查看这个线程是否处于sleep标志中。如果发现他还需要继续睡眠,则重新进行调度选择,直到选择一个有权执行的线程为止。
 如果很不幸,400ms到了,但是系统很忙,调度算法在很长一段时间也没有选择到这个线程,那这么线程就很继续休眠。于是说,这个Sleep(400);将导致这
个线程会休眠大于等于400MS的时间。
系统将在大约的指定秒数内使线程不可高度。不错,如果告诉系统,想睡眠100MS,那么可以睡大约这么长的时间,但也也可能睡眠数秒或数分钟。记住,
WINDOWS不是个实时操作系统。虽然线程可能在规定的时间被唤醒,但是它能否做到,取决于系统中还有什么操作正在进行。
但最好不要这么做,最好不要再初始化函数里创建线程