【问题标题】:POSIX TIMER- Have multiple timersPOSIX TIMER - 有多个定时器
【发布时间】:2011-05-23 08:37:48
【问题描述】:

我试图在我的系统中有两个计时器用于两个不同的目的,但我不明白为什么它不起作用。有人可以帮我吗?另外,处理程序代码是否应该是最低限度的,这样任务本身就不会干扰滴答声?我也可以定义单独的处理程序吗?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <netinet/in.h>
#include <linux/socket.h>
#include <time.h>


#define SIGTIMER (SIGRTMAX)
#define SIG SIGUSR1
static timer_t     tid;
static timer_t     tid2;

void SignalHandler(int, siginfo_t*, void* );
timer_t SetTimer(int, int, int);

int main(int argc, char *argv[]) {


    struct sigaction sigact;
    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = SA_SIGINFO;
    sigact.sa_sigaction = SignalHandler;
    // set up sigaction to catch signal
    if (sigaction(SIGTIMER, &sigact, NULL) == -1) {
        perror("sigaction failed");
        exit( EXIT_FAILURE );
    }

    // Establish a handler to catch CTRL+c and use it for exiting.
    sigaction(SIGINT, &sigact, NULL);
    tid=SetTimer(SIGTIMER, 1000, 1);

    struct sigaction sa;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_SIGINFO;
    sa.sa_sigaction = SignalHandler;
    // set up sigaction to catch signal
    if (sigaction(SIG, &sa, NULL) == -1) {
        perror("sa failed");
        exit( EXIT_FAILURE );
    }

    // Establish a handler to catch CTRL+c and use it for exiting.
    sigaction(SIGINT, &sa, NULL);
    tid2=SetTimer(SIG, 1000, 3);
    for(;;);
    return 0;
}

void SignalHandler(int signo, siginfo_t* info, void* context)
{
    if (signo == SIGTIMER) {
        printf("Command Caller has ticked\n");

    }else if (signo == SIG) {
        printf("Data Caller has ticked\n");

    } else if (signo == SIGINT) {
        timer_delete(tid);
        perror("Crtl+c cached!");
        exit(1);  // exit if CRTL/C is issued
    }
}
timer_t SetTimer(int signo, int sec, int mode)
{
    static struct sigevent sigev;
    static timer_t tid;
    static struct itimerspec itval;
    static struct itimerspec oitval;

    // Create the POSIX timer to generate signo
    sigev.sigev_notify = SIGEV_SIGNAL;
    sigev.sigev_signo = signo;
    sigev.sigev_value.sival_ptr = &tid;

    if (timer_create(CLOCK_REALTIME, &sigev, &tid) == 0) {
        itval.it_value.tv_sec = sec / 1000;
        itval.it_value.tv_nsec = (long)(sec % 1000) * (1000000L);

        if (mode == 1) {
            itval.it_interval.tv_sec = itval.it_value.tv_sec;
            itval.it_interval.tv_nsec = itval.it_value.tv_nsec;
        }
        else {
            itval.it_interval.tv_sec = 0;
            itval.it_interval.tv_nsec = 0;
        }

        if (timer_settime(tid, 0, &itval, &oitval) != 0) {
            perror("time_settime error!");
        }
    }
    else {
        perror("timer_create error!");
        return NULL;
    }
    return tid;
}

【问题讨论】:

    标签: c linux posix


    【解决方案1】:

    当您使用此tid2=SetTimer(SIG, 1000, 3); 定义您的第二个计时器时,您的代码将此计时器配置为一次性计时器

        if (mode == 1) {
            itval.it_interval.tv_sec = itval.it_value.tv_sec;       // here you arm the timer periodically (that's the meaning of it_interval
            itval.it_interval.tv_nsec = itval.it_value.tv_nsec;
        }
        else {
            itval.it_interval.tv_sec = 0;     // here you arm the timer once
            itval.it_interval.tv_nsec = 0;
        }
    

    如果您使用 mode=1 配置第二个计时器,例如 tid2=SetTimer(SIG, 1000, 4);,您将在控制台上获得它:

    Command Caller has ticked
    Data Caller has ticked
    Command Caller has ticked
    Data Caller has ticked
    Command Caller has ticked
    Data Caller has ticked
    ^CCrtl+c cached!: Success
    

    您可以为计时器使用不同的处理程序,因为您使用不同的信号来捕捉它们的到期时间。

    【讨论】:

    • 我在计时器部分发现了一个错误。我发现代码随机冻结。任何的想法?我在 Data Caller Signal 上调用了一个函数。
    • @user489152 : 问一个关于你的新问题的新问题,并提供有关被调用函数的详细信息,也许问题隐藏在其中。
    • 我这里有一些竞争条件。会不会是 printf 语句的原因??
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-18
    • 2020-04-26
    • 1970-01-01
    相关资源
    最近更新 更多