C 以特定的时间间隔执行函数

C 以特定的时间间隔执行函数,c,timer,pthreads,C,Timer,Pthreads,任务是每x(比如x=10)秒执行一个函数(比如说Processfunction()) 有了下面的代码,我可以每隔x秒调用Processfunction() 问题:如何处理函数执行时间超过10秒的情况 一种方法是使用一个标志来指示Processfunction()执行的结束,并在调用Processfunction()之前进行检查。 有更好的方法吗 #包括 #包括//用于sleep()和usleep() void*timer读取(void*timer_parms){ 结构itimerspec新值;

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

有了下面的代码,我可以每隔x秒调用
Processfunction()

问题:如何处理函数执行时间超过10秒的情况

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


#包括
#包括//用于sleep()和usleep()
void*timer读取(void*timer_parms){
结构itimerspec新值;
int max_exp,fd;
现在构造timespec;
uint64_t exp;
ssize_t s;
结构定时器参数*p=(结构定时器参数*)定时器参数;
printf(“starttimer Start\n”);
/*使用初始值创建时钟\实时绝对计时器
命令行中指定的过期时间和间隔*/
if(clock\u gettime(clock\u REALTIME,&now)=-1)
处理错误(“时钟获取时间”);
new_value.it_value.tv_sec=now.tv_sec;
new\u value.it\u value.tv\u nsec=now.tv\u nsec+p->tv\u nsec;
新值.it_interval.tv_sec=p->tv_sec;
新建值.it\u interval.tv\u nsec=p->tv\u nsec;
//max_exp=5;//次数
fd=timerfd\u create(时钟实时,0);
如果(fd==-1)
处理错误(“timerfd\u创建”);
if(timerfd_settime(fd、TFD_TIMER_ABSTIME和new_value,NULL)=-1)
处理错误(“timerfd\u设置时间”);
printf(“计时器已启动\n”);
while(1)//继续检查
{
s=读取(fd、exp、sizeof(uint64_t));
如果(s!=sizeof(uint64_t))
处理错误(“读取”);
Processfunction();//假设在X秒后调用此函数
}
返回NULL;
}
int main(){
结构定时器参数定时器参数对象;
int res;void*线程结果;
定时器参数对象电视秒=10;
//timer_params_obj.tv_nsec=10000000;//10ms
定时器参数对象tv nsec=0;
pthread_t pt;
pthread_create(&pt、NULL、timerthread和timer_params_obj);
//线程正在运行,将每隔10秒调用Processfunction()
}

为什么需要计时器来完成此操作

您可以只测量执行时间,并根据经过的时间与所需间隔持续时间的关系进行睡眠

例如:

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

我有一个几乎相同的用例,只是我需要它是跨平台的C++11,并且需要同时执行其他任务,而不是睡觉。以下是我的代码,以防对某人有用:

// TimeT.h - Calls the passed function if the minimum time interval has elapsed
#ifndef TIME_T_H_
#define TIME_T_H_

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

#endif // TIME_T_H_
//TimeT.h-如果已过最短时间间隔,则调用传递的函数
#ifndef时间_
#定义时间_
#包括
///跟踪自调用execution()以来的时间,并且仅
///如果已过最短时间间隔,则调用传递的函数
///@见https://stackoverflow.com/questions/2808398/easily-measure-elapsed-time 对于我基于此的代码
模板
结构周期
{
周期性(TimeT持续时间=TimeT(1))
:开始(标准::时钟::系统时钟::现在()
,期间\持续时间(持续时间)
,上一个持续时间(TimeT::zero())
{};
模板
TimeT执行(F func,Args&…Args)
{
自动持续时间=标准::计时::持续时间
(std::chrono::system_clock::now()-start);
if(持续时间>上一个持续时间+期间持续时间)
{

std::forward(func)(std::forward.

您不希望有两个
Processfunction()
同时运行?如果执行时间比正常允许的间隔时间长,您是希望延迟调用还是跳过调用?是的,我不希望它同时运行。如果执行时间长,我希望跳过/延迟调用。+1-是-这是我的做法。计时器通常是使用不当:(这可以在没有linux特定代码(boost或c++11)和睡眠的情况下完成吗?同时程序还有其他事情要做。@andrewhund您可以使用boost.Asio的截止时间计时器异步等待特定时间。由于异步程序流,您可能需要重新构造代码(如果情况并非如此)@moooeep是的,这也是一个很好的方法,我以前也用过。但是,我想把代码放在一个非常小的示例中,我发现典型的开发人员很难立即掌握asio,所以我想避免太多的复杂性。我在下面的另一个答案中列出了我使用的解决方案,以防其他人遇到这个问题hat无法使用已接受答案的依赖项。
$ 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
// TimeT.h - Calls the passed function if the minimum time interval has elapsed
#ifndef TIME_T_H_
#define TIME_T_H_

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

#endif // TIME_T_H_
#include "TimeT.h"    

#include <iostream>
#include <thread>

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