c ++使用线程作为计时器

时间:2011-07-18 11:32:07

标签: c++ multithreading sleep thread-sleep

我的项目有一个不同的线程可以制作一些东西。

一切都好,但是我希望每个20ms都有一些函数(例如),但是考虑到花在函数上的时间......我试着更好地解释......我调用函数,函数用了6ms退出,所以我希望线程睡眠14ms(20 - 6),下次调用时,函数花费12ms,所以睡眠时间只有8ms .... 我怎样才能做到这一点? 这是我的代码:

// thread constructor
DWORD dwThreadId, dwThrdParam = 1;  
HANDLE thread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)workerFunc, &dwThrdParam, 0, &dwThreadId );

// thread function
DWORD WINAPI workerFunc( LPDWORD lpdwParam )
{
    while( true )
    {
        myFunction( );
        Sleep( ??? );
    }
    return 0;
}

谢谢!

4 个答案:

答案 0 :(得分:2)

这个怎么样:

clock_t start, end;
while( true )
{
    start = clock();
    myFunction( );
    end = clock();
    Sleep(20-(end-start)*CLOCKS_PER_SEC/1000.0);
}

答案 1 :(得分:2)

一种简单的方法是将线程发送到休眠状态一段时间:

void periodic_function()
{
  /* function body */

  timestamp = get_time(); // pseudo-function
  remaining_sleep_time = std::min(0, 20 - (timestamp - last_timestamp));
  last_timestamp = timestamp;
  milli_sleep_callback(remaining_sleep_time, periodic_function);
}

您需要get_time()和睡眠功能的合适稳定时钟功能 - 尝试<chrono><tr1/chrono>标头。在这个例子中,我假设你有一个计时器回调(比如在boost.ASIO中),但你也可以进行无限循环或类似的事情。

如果函数体永远不会超过20ms,此函数将起作用,但如果您的函数需要更长,它将快速赶上。如果你想同步到全球20ms的节奏,你必须添加另一个全局步数或类似的东西。

答案 2 :(得分:1)

在致电myFunc之前和致电myFunc之后使用GetTickCount。差异为您提供myFunc所花费的时间。请注意,此时间包括由于OS调度而导致的进程所花费的时间。

答案 3 :(得分:0)

如果您需要精确度,请在程序启动时使用NtSetTimerResolution来设置定时器分辨率。是的,它是无证的功能,但效果很好。您也可以使用NtQueryTimerResolution来了解计时器分辨率(在设置之前和设置新分辨率之后)。

您需要使用GetProcAddress中的NTDLL.DLL动态获取这些函数的地址,因为它未在标头或任何LIB文件中声明。

以这种方式设置计时器分辨率会影响Sleep,Windows计时器,返回当前时间的函数等。