执行一个方法用C每x秒(Execute a method every x seconds in C)

2019-07-05 14:40发布

是否有执行一些功能的计时器的工作的一个例子使用C.每x秒量

我会很感激的例子工作代码。

Answer 1:

你可以生成一个新的线程:

void *threadproc(void *arg)
{
    while(!done)
    {
        sleep(delay_in_seconds);
        call_function();
    }
    return 0;
}
...
pthread_t tid;
pthread_create(&tid, NULL, &threadproc, NULL);

或者,你可以设置与报警alarm(2)setitimer(2)

void on_alarm(int signum)
{
    call_function();
    if(!done)
        alarm(delay_in_seconds);  // Reschedule alarm
}
...
// Setup on_alarm as a signal handler for the SIGALRM signal
struct sigaction act;
act.sa_handler = &on_alarm;
act.sa_mask = 0;
act.sa_flags = SA_RESTART;  // Restart interrupted system calls
sigaction(SIGALRM, &act, NULL);

alarm(delay_in_seconds);  // Setup initial alarm

当然,这两种方法都有,我们在调用该函数周期性的需要是线程安全的问题。

该信号的方法是特别危险的,因为它也必须是异步安全的,这是很难做到的-即使是一些简单如printf是不安全的,因为printf可能分配内存,如果SIGALRM中断调用malloc ,你遇到麻烦,因为malloc是不可重入。 所以,我不会推荐信号的方法,除非你做的是设置一个标志,后来被一些其他的功能,这使你回到同一个地方线程版本检查信号处理程序。



Answer 2:

有各种传统的方式来做到这一点使用间隔定时器和信号,但是我要提出两个现代化的方法:

使用POSIX计时器

的POSIX timer_create功能创建可被配置成当所述定时器期满,提供一次性或定期通知的定时器。 在创建定时器,你可以通过一个信号或一个新的线程要么交付要求。 因为使用正确的信号是复杂的(大约有你,不能从信号处理程序做了什么,并打破规则往往“似乎工作”,直到你倒霉的严格规定),我会建议使用基于线程的交付。

用螺纹滚你自己的计时器

这是真的,因为它听起来那么容易。 创建一个新的线程进入一个循环,睡觉和做什么你需要完成每一个需要的时间已经过去的时间。



Answer 3:

IMO,在这种情况下,你可以使用gettimeofday()到算法,如:使用了这样的while(1)计数当前时间和last_execution_time之间的时间差,每次的差别达到1秒,更新last_execution_time并调用应该功能在每隔1秒运行。

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

#DEFINE DESIRED_INTERVAL 1  //1 second
int get_tv_cur_minus_given(struct timeval *tv, struct timeval *tp_given, int *sign)
{
    struct timeval tp_cur;


    gettimeofday(&tp_cur,NULL);

    tv->tv_sec  = tp_cur.tv_sec - tp_given->tv_sec;
    tv->tv_usec = tp_cur.tv_usec - tp_given->tv_usec;

    if(tv->tv_sec > 0) {
        *sign = 1;
        if(tv->tv_usec < 0) {
            tv->tv_sec--;
            tv->tv_usec = 1000000 + tv->tv_usec;
        }
    }else
    if(tv->tv_sec == 0) {
        if(tv->tv_usec == 0)
            *sign = 0;
        else
        if(tv->tv_usec < 0) {
            *sign = -1;
            tv->tv_usec *= -1;
        }else
            *sign = 1;
    }else {
        *sign = -1;
        if(tv->tv_usec > 0) {
            tv->tv_sec++;
            tv->tv_usec = 1000000 - tv->tv_usec;
        }else
        if(tv->tv_usec < 0)
            tv->tv_usec *= -1;
    return 0;
        }
}

int main()
{
    struct timeval      tv_last_run;
    struct timeval  tv_diff;
    int sign;


    while(true)
    {

     get_tv_cur_minus_given(&tv_diff, &tv_last_run, &sign);

        if(tv_diff.tv_sec > DESIRED_INTERVAL)
        {
            gettimeofday(&tv_last_run,NULL);
            printf("\ncall the func here");
        }
    }

    return 0;
}

如果你需要不同的线程出主线程,然后移动内部主线路()到一个函数指针,并使之通过在pthread_create功能,如:

void *threadproc(void *arg)
{
   while(1)
   {
       //put the same lines as inside main() function in above code snippet. .
   }
}
pthread_create(&tid, NULL, &threadproc, NULL);


文章来源: Execute a method every x seconds in C