简体   繁体   中英

c++ use thread as timer

I have my project with a different thread that make some stuff.

It's all ok, but I wish have some function called each 20ms (for example), but considering the time spent to the function... I try to explain better... I call the function, and the function spent 6ms to exit, so I wish that the thread sleeps 14ms (20 - 6), the next time that is called, the function spent 12ms, so the sleep will be only 8ms.... how can I do this? here is my code:

// 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;
}

thanks!

What about this:

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

A simple approach would be to send the thread to sleep for a variable amount of time:

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);
}

You'll need a suitable steady clock function for get_time() and a sleep function - try the <chrono> or <tr1/chrono> header. In this example I've assumed that you have a timer callback (like in boost.ASIO), but you could also make an infinite loop or something like that.

This function will work if the function body never exceeds 20ms, though it'll do a quick catch-up if your function ever takes longer . If you want to synchronize to a global 20ms rhythm, you'd have to add another global step counter or something like that.

Use GetTickCount before calling myFunc and after calling myFunc . The difference gives you the time spent in myFunc . Note that this time includes the time spent by the process due to OS scheduling.

If you need precision, use NtSetTimerResolution when program starts up to set timer resolution. Yes, it is undocumented function, but works well. You may also use NtQueryTimerResolution to know timer-resolution (before setting and after setting new resolution to be sure).

You need to dynamically get the address of these functions using GetProcAddress from NTDLL.DLL , as it is not declared in header or any LIB file.

Setting timer resolution this way would affect Sleep , Windows timers, functions that return current time etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM