任务是执行功能(说Processfunction()
每x(比如说X = 10)秒。
下面的代码,我能叫Processfunction()
每x秒。
问:如何处理这种情况的功能需要超过10秒完成执行的情况?
一种方法是有一个标志来指示结束Processfunction()
执行和调用之前检查它Processfunction()
有一个更好的方法吗 ?
#include <pthread.h>
#include <unistd.h> // 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
}
为什么你需要为这个定时器吗?
你可以只测量执行时间,根据经过时间所需的间隔区间的关系采取的睡眠。
例:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
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 <iostream>
#include <chrono>
/// 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<typename TimeT = std::chrono::milliseconds>
struct periodic
{
periodic(TimeT duration = TimeT(1)):
start(std::chrono::system_clock::now()),
period_duration(duration),
previous_duration(TimeT::zero())
{};
template<typename F, typename ...Args>
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<decltype(func)>(func)(std::forward<Args>(args)...);
previous_duration = duration;
}
return duration;
}
std::chrono::time_point<std::chrono::system_clock> 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));
}
}
这个实现是基于修改关于测量经过时间计算器这个问题 。