在C中每x秒执行一次方法

Fir*_*rre 5 c linux ubuntu timer intervals

是否有一个工作计时器的例子,它使用C每x秒执行一些函数.

我很欣赏一个工作代码示例.

Ada*_*eld 14

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

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

或者,您可以使用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
Run Code Online (Sandbox Code Playgroud)

当然,这两种方法都存在这样的问题,即您定期调用的函数需要是线程安全的.

该信号的方法是特别危险的,因为它也必须是异步安全的,这是很难做到的-即使是一些简单,只需printf是不安全的,因为printf可能分配内存,如果SIGALRM中断调用malloc,你就麻烦了,因为malloc是不可重入.所以我不建议使用signal方法,除非你所做的只是在信号处理程序中设置一个标志,后来由其他一些函数检查,这会让你回到与线程版本相同的位置.


R..*_*R.. 6

使用间隔定时器和信号有各种传统方法可以做到这一点,但我将提出两种现代方法:

使用POSIX定时器

POSIX timer_create函数创建一个计时器,可以配置为在计时器到期时提供一次性或定期通知.创建计时器时,您可以通过信号或新线程请求传递.由于正确使用信号很复杂(对信号处理程序可以做什么和不做什么都有严格的规定,并且在你不幸的情况下打破规则经常"似乎工作"),我建议使用基于线程的传递.

用线程滚动自己的计时器

这真的很容易听起来.创建一个进入循环休眠状态的新线程,并在每次所需时间结束时执行所需操作.