Problem in Timers and signal

前端 未结 4 1952
别跟我提以往
别跟我提以往 2020-12-06 03:35

I have implemented a POSIX timer using timer_create( ) API, and this will generate SIGUSR1 when the timer expires for which i have put a handler code. Now the problem is, if

相关标签:
4条回答
  • 2020-12-06 03:55

    The question is whether you really need to use signals. You may think of using callback that will be called when the timer expires:

    void cbf(union sigval);
    struct sigevent sev;
    timer_t timer;
    
    sev.sigev_notify = SIGEV_THREAD;
    sev.sigev_notify_function = cbf; //this function will be called when timer expires
    sev.sigev_value.sival_ptr = (void*) arg;//this argument will be passed to cbf
    timer_create(CLOCK_MONOTONIC, &sev, &timer);
    

    The callback function will be called in a new thread.

    0 讨论(0)
  • 2020-12-06 03:58

    Use another RT signals. See answers on Is there any way to create a user defined signal in Linux?

    0 讨论(0)
  • 2020-12-06 04:01

    No, there is no easy way. Why don't you use SIGUSR2 instead for your timers if you have something else generating SIGUSR1 together with your timer. If that is not enough, use one of the real time signals for your application.

    If it must be able to handle the same signal from the timer and some other source, then depending on how fast, how many, what system, etc etc you could try setting a timestamp before registering a timer on when the timer will approximately exit, and then in the signal handler try to deduce if it was within time margin. I would strongly advise not to use this approach, but instead redesign what you are doing.

    0 讨论(0)
  • 2020-12-06 04:08

    Will this work for you? (Modified the code from example in timer_create man page.)

    #include <stdlib.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <signal.h>
    #include <time.h>
    
    #define CLOCKID CLOCK_REALTIME
    #define SIG SIGUSR1
    timer_t timerid;
    
    
    static void handler(int sig, siginfo_t *si, void *uc)
    {
        if(si->si_value.sival_ptr != &timerid){
            printf("Stray signal\n");
        } else {
            printf("Caught signal %d from timer\n", sig);
        }
    }
    
    int main(int argc, char *argv[])
    {
        struct sigevent sev;
        struct itimerspec its;
        long long freq_nanosecs;
        sigset_t mask;
        struct sigaction sa;
    
        printf("Establishing handler for signal %d\n", SIG);
        sa.sa_flags = SA_SIGINFO;
        sa.sa_sigaction = handler;
        sigemptyset(&sa.sa_mask);
        sigaction(SIG, &sa, NULL);
    
        sev.sigev_notify = SIGEV_SIGNAL;
        sev.sigev_signo = SIG;
        sev.sigev_value.sival_ptr = &timerid;
        timer_create(CLOCKID, &sev, &timerid);
        /* Start the timer */
    
        its.it_value.tv_sec = 10;
        its.it_value.tv_nsec = 0;
        its.it_interval.tv_sec = its.it_value.tv_sec;
        its.it_interval.tv_nsec = its.it_value.tv_nsec;
    
        timer_settime(timerid, 0, &its, NULL);
        sleep(100);
        exit(EXIT_SUCCESS);
    }
    

    When signal from timer is caught Caught signal 10 from timer will be displayed. Otherwise Stray signal will be displayed.

    0 讨论(0)
提交回复
热议问题