以特定间隔执行function

任务是每隔x(比如x = 10)秒执行一个函数(比如Processfunction() )。

使用下面的代码,我可以每隔x秒调用一次Processfunction()

问题:如何处理函数完成执行需要10秒以上的情况?

一种方法是使用一个标志来指示Processfunction()执行的结束并在调用Processfunction()之前检查它。 有一个更好的方法吗 ?


 #include  #include  // for sleep() and usleep() void *timerthread(void *timer_parms) { struct itimerspec new_value; int max_exp, fd; struct timespec now; uint64_t exp; ssize_t s; struct timer_params *p =(struct timer_params*)timer_parms; printf("starttimer Start\n"); /* Create a CLOCK_REALTIME absolute timer with initial expiration and interval as specified in command line */ if (clock_gettime(CLOCK_REALTIME, &now) == -1) handle_error("clock_gettime"); new_value.it_value.tv_sec = now.tv_sec; new_value.it_value.tv_nsec = now.tv_nsec + p->tv_nsec; new_value.it_interval.tv_sec = p->tv_sec; new_value.it_interval.tv_nsec = p->tv_nsec; //max_exp = 5; //No of times fd = timerfd_create( CLOCK_REALTIME , 0); if (fd == -1) handle_error("timerfd_create"); if (timerfd_settime(fd, TFD_TIMER_ABSTIME, &new_value, NULL) == -1) handle_error("timerfd_settime"); printf("timer started\n"); while(1) // keep checking { s = read(fd, &exp, sizeof(uint64_t)); if (s != sizeof(uint64_t)) handle_error("read"); Processfunction(); // Say after X seconds call this function } return NULL; } int main() { struct timer_params timer_params_obj; int res;void *thread_result; timer_params_obj.tv_sec = 10; //timer_params_obj.tv_nsec = 10000000 ; //10ms timer_params_obj.tv_nsec = 0 ; pthread_t pt; pthread_create(&pt, NULL, timerthread, &timer_params_obj); // thread is running and will call Processfunction() every 10 sec } 

为什么你需要一个计时器呢?

您可以根据经过时间与所需间隔持续时间的关系来测量执行时间并进行hibernate。

例:

 #include  #include  #include  #include  int main() { srand(1); for (;;) { double interval = 10; /* seconds */ /* start time */ time_t start = time(NULL); /* do something */ int duration = rand() % 13; printf("%2d seconds of work started at %s", duration, ctime(&start)); sleep(duration); /* end time */ time_t end = time(NULL); /* compute remaining time to sleep and sleep */ double elapsed = difftime(end, start); int seconds_to_sleep = (int)(interval - elapsed); if (seconds_to_sleep > 0) { /* don't sleep if we're already late */ sleep(seconds_to_sleep); } } return 0; } 

输出:

 $ gcc test.c && ./a.out 0 seconds of work started at Sun Mar 17 21:20:28 2013 9 seconds of work started at Sun Mar 17 21:20:38 2013 11 seconds of work started at Sun Mar 17 21:20:48 2013 4 seconds of work started at Sun Mar 17 21:20:59 2013 1 seconds of work started at Sun Mar 17 21:21:09 2013 ^C 

我有一个几乎相同的用例,除了我需要它是跨平台的C ++ 11并且需要在此期间做其他任务而不是睡觉。 这是我的代码,以防它对某人有用:

 #include  #include  /// Tracks the time since execution() was called, and only /// Calls the passed function if the minimum time interval has elapsed /// @see https://stackoverflow.com/questions/2808398/easily-measure-elapsed-time for the code I based this on template struct periodic { periodic(TimeT duration = TimeT(1)): start(std::chrono::system_clock::now()), period_duration(duration), previous_duration(TimeT::zero()) {}; template TimeT execution(F func, Args&&... args) { auto duration = std::chrono::duration_cast< TimeT> (std::chrono::system_clock::now() - start); if(duration > previous_duration + period_duration) { std::forward(func)(std::forward(args)...); previous_duration = duration; } return duration; } std::chrono::time_point start; // The minimum duration to wait before the function can be called again TimeT period_duration; // The duration between startup and the last time the function was called TimeT previous_duration; }; 

以下是使用它的示例:

 int main(int argc, char* argv[]) { periodic<> callIfMinPeriodPassed(std::chrono::milliseconds(1)); std::size_t num_periods; while(true) { callIfMinPeriodPassed.execution( [&num_periods]() { std::cout << ++num_periods << "timesteps have passed\n" }); // do other stuff here, this example will work // but spins at 100% CPU without the sleep std::this_thread::sleep_for(std::chrono::milliseconds(1)); } } 

此实现基于对此堆栈溢出问题的修改, 该问题是关于测量经过的时间 。