每隔一段时间执行一次操作

时间:2009-06-22 14:41:38

标签: c++ c unix

我想在某个超时时间执行操作,就像开火一样 事件。我想出了如何每n秒,但不是1.5 秒。这就是我所拥有的。请建议如何处理我的案子:

void Publish()
{
    static  int local_time=time(NULL);

     int current_time = time (NULL);
     if((current_time+PUBLISH_TIMEOUT)>local_time)
      {
           fireEvent();
            local_time=current_time;
      } 
}

7 个答案:

答案 0 :(得分:1)

gettimeofday()返回微秒,因此您可以使用它而不是time() - 请参阅此函数填充的struct timeval定义。

查看man gettimeofday了解详情。

答案 1 :(得分:0)

这将返回自应用程序启动以来以毫秒为单位的待机时间。它使用机器时钟,因此在应用程序运行时更改时钟的时间很可能会让它感到困惑。在你的情况下,我会在我的事件对象中添加一个计划时间,并在计划时间< = msec()

时触发
 clock_t msec() {
    static struct timeval msec_base;
    struct timeval now;

    long seconds, useconds; 
    if (!msec_base.tv_usec)
        gettimeofday(&msec_base, NULL);
    gettimeofday(&now, NULL);

    seconds  = now.tv_sec  - msec_base.tv_sec;
    useconds = now.tv_usec - msec_base.tv_usec;

    return ((seconds) * 1000 + useconds/1000.0);
}

答案 2 :(得分:0)

基于尼克回答的完整解决方案:

#include <sys/time.h>
#include <iostream>
#include <cstdlib>

using namespace std;

int TOTAL_PROCESSES;
double TIMEOUT;
int process()
{

    static struct timeval msec_base;
    struct timeval now;

    long seconds, useconds; 
    if (!msec_base.tv_usec)
        gettimeofday(&msec_base, NULL);

    gettimeofday(&now, NULL);

    seconds  = now.tv_sec  - msec_base.tv_sec;
    useconds = now.tv_usec - msec_base.tv_usec;

    double time_diff=seconds+ useconds/100000.0;

    if(TIMEOUT < time_diff)
    {
        cout<<TIMEOUT <<" seconds...\n";
        msec_base=now;

        return 1;
    }
     return 0;

}

int main(int argc, char** argv)
{
    if(argc < 3)
    {
        cout<<"Error: missing TIMOUT and total time to fire\n";
        return -1;

    }

    TIMEOUT       = atof(argv[1]);
    TIMES_TO_FIRE = atoi(argv[2]);

    cout << "INFO: TIMEOUT="<<TIMEOUT<<", TIMES_TO_FIRE ="<< TIMES_TO_FIRE <<endl; 


    int i=0;
    while (i< TIMES_TO_FIRE)
      i+=process();

    return 0;
}

答案 3 :(得分:0)

答案 4 :(得分:0)

如果这是C,为什么不使用setitimer()SIGALRM

setitimer()做什么,在一定的时间间隔(你可以指定毫秒),它会触发SIGALRM信号。然后,您可以设置程序,使其具有响应该信号的功能。

alarm()函数与setitimer()做同样的事情 - 但是alarm()只能用1秒间隔(不是1.5秒等)。那就说this page给出了如何进行教程处理中断。使用这种方法可以为自己节省大量的时间计算代码。

答案 5 :(得分:0)

我知道这不是第二种,但你可以使用rdtsc寄存器,具体取决于你的处理器...更多细节here(用于测量linux中的时间流逝)

答案 6 :(得分:0)

@puzzlecracker

CPU负载不是问题吗?您的例程会不断检查条件不必要的次数。当它遗漏时我会使用usleep():

...

 if(TIMEOUT < time_diff)
{
    cout<<TIMEOUT <<" seconds...\n";
    msec_base=now;

    return 1;
} else usleep(10);

...

其他进程的生成时间,并不会对您的代码响应性造成任何惩罚。

更好的解决方案是使用不同方法的clock_nanosleep(),如线程计时器。