定期运行一段代码而不使用睡眠

时间:2015-12-29 11:00:20

标签: c linux windows

我有一个函数,并且以特定的间隔调用。我需要检查之前调用的时间和当前时间。如果函数调用之间的差异是10毫秒,那么执行一些代码。不应该使用睡眠,因为其他一些东西并行执行。我编写了以下代码,并且每10毫秒调用一次函数,但我计算的差异有时会减少1或2毫秒。什么是计算差异的最佳方法?

fxn()
{
    int logCurTime;
    static int logPrevTime = 0, logDiffTime = 0;
    getCurrentTimeInMilliSec(&logCurTime);          

    if (logPrevTime > 0)
        logDiffTime += logCurTime - logPrevTime;

    if (logCurTime <= logPrevTime)
        return;

    if (logDiffTime >= 10)
    {
        ...
        ...
        logDiffTime = 0;
    }
    logPrevTime = logCurTime;
}

例如: fxn被调用10次,间隔为10毫秒。一些实例logDiffTime只有8或9,下一个实例它会占用剩余时间。即11或12。

3 个答案:

答案 0 :(得分:1)

使用sleep()来获取在特定时间间隔内执行的代码确实是一个坏主意。将您的函数注册为定时器中断的处理程序。然后它将按时非常精确地调用。

如果你在你的功能中做了很重的事情,那么你应该在另一个线程中做这件事,因为当你的功能耗费太长时你会遇到麻烦。 (它将从头开始再次调用。)

在posix(linux)中你可以这样做

#include <sys/time.h>
#include <stdio.h>
#include <signal.h>

if (signal (SIGALRM, fxn) == SIG_ERR)
    perror ("Setting your function as timer handler failed");
unsigned seconds = 42;//your time
struct itimerval old, new_time;
new_time.it_interval.tv_usec = 0;
new_time.it_interval.tv_sec = 0;
new_time.it_value.tv_usec = 0;
new_time.it_value.tv_sec = (long int) seconds;
if (setitimer (ITIMER_REAL, &new_time, &old) != 0)
    perror ("Setting the timer failed");

或在Windows中:

#include <Windows.h>

void Fxn_Timer_Proc_Wrapper(HWND,UINT,UINT_PTR,DWORD){
    fxn();
}

unsigned seconds = 42;//your time
UINT_PTR timer_id;
if ( (timer_id = SetTimer(NULL,NULL,seconds *1000,(TIMERPROC) Fxn_Timer_Proc_Wrapper) == NULL){
    //failed to create a timer
}

答案 1 :(得分:0)

这可能不是你想要的,但我觉得应该澄清: sleep调用只挂起调用线程,而不是进程的所有线程。因此,当其中一个线程处于休眠状态时,您仍然可以运行并行线程。 有关更多信息,请参阅此问 Do sleep functions sleep all threads or just the one who call it?

要解决您的问题,您应该使用定时器中断注册您的功能。请参阅另一个答案,了解如何做到这一点。

答案 2 :(得分:0)

10ms处于可实现的边缘,见stack overflow : 1ms timer 。但是,关于如何获得10毫秒的一些建议确实出来了。

  1. timerfd_create允许您的程序使用select等待。
  2. timer_settime允许您的程序请求10ms间隔。
  3. Linux上的警告是: -

    1. 可能无法安排 - 操作系统可能正在忙着做其他事情。
    2. 可能不准确 - 因为10ms似乎是有效的最短间隔,可能是+/- 1或2 ms。