如何一次又一次地生成相同的信号(SIGALRM)?

时间:2014-07-20 08:28:00

标签: c linux timer signals scheduled-tasks

我们正在尝试使用sigaction和setitimer从我们的三个函数中的while(1)循环中控制,我们现在面临的问题是只生成一次SIGALRM并且下一次它不生成即我们能够从fun1()的while(1)而不是fun2()的while(1)获取控制权。 你能否提出解决这个问题的方法。请找下面的代码。

#define INTERVAL 500
void fun1();
void fun2();
void fun3();
void timer_handler(int );
struct itimerval it_val;
int count=0;
void timer_handler (int signum)
{

    L1:
        printf(“\nScheduler Called .. Calling Fun1″);

        if(count==0){
            count++;
            fun1();
        }
        printf(“\nScheduler Called .. Calling Fun2″);
        if(count==1){
            count++;
            fun2();
         }
     printf(“\nScheduler Called .. Calling Fun3″);
         if(count==2){
             count++;
             fun3();
         }
         count=0;
     goto L1;
}

void fun1()
{

    struct sigaction sa;

    /* Install timer_handler as the signal handler for SIGVTALRM. */
    memset (&sa, 0, sizeof (sa));
    sa.sa_handler = &timer_handler;

    /* Configure the timer to expire  */
    it_val.it_value.tv_sec = INTERVAL/1000;
    it_val.it_value.tv_usec = (INTERVAL*1000) % 1000000;

    it_val.it_interval.tv_sec = INTERVAL/1000;;
    it_val.it_interval.tv_usec=(INTERVAL*1000) % 1000000;
    /* Start a timer. It counts down whenever this process is*/

    sigaction (SIGALRM, &sa, NULL);
    setitimer (ITIMER_REAL, &it_val, NULL);
    while (1){
        printf(“\nfun1″);
    }

}

 void fun2()
{

    struct sigaction sa;

    /* Install timer_handler as the signal handler for SIGVTALRM. */
    memset (&sa, 0, sizeof (sa));
    sa.sa_handler = &timer_handler;

    /* Configure the timer to expire  */
    it_val.it_value.tv_sec = INTERVAL/1000;
    it_val.it_value.tv_usec = (INTERVAL*1000) % 1000000;

    it_val.it_interval.tv_sec = INTERVAL/1000;;
    it_val.it_interval.tv_usec=(INTERVAL*1000) % 1000000;
    /* Start a timer. It counts down whenever this process is*/

    sigaction (SIGALRM, &sa, NULL);
    setitimer (ITIMER_REAL, &it_val, NULL);
    while (1){
        printf(“\nfun2″);
    }

}


 void fun3()
{

    struct sigaction sa;

    /* Install timer_handler as the signal handler for SIGVTALRM. */
    memset (&sa, 0, sizeof (sa));
    sa.sa_handler = &timer_handler;

    /* Configure the timer to expire  */
    it_val.it_value.tv_sec = INTERVAL/1000;
    it_val.it_value.tv_usec = (INTERVAL*1000) % 1000000;

    it_val.it_interval.tv_sec = INTERVAL/1000;;
    it_val.it_interval.tv_usec=(INTERVAL*1000) % 1000000;
    /* Start a timer. It counts down whenever this process is*/

    sigaction (SIGALRM, &sa, NULL);
    setitimer (ITIMER_REAL, &it_val, NULL);
    while (1){
        printf(“\nfun3″);
    }

}
int main(){
    timer_handler(1);
    return 0;
}

2 个答案:

答案 0 :(得分:1)

当信号传递时,它会自动屏蔽,直到动作函数返回。

一般情况下,您希望信号动作功能绝对最小。你所编写的内容实际上是一个递归动作函数,其中包含大部分程序。即使它确实有效,你也会吃堆栈,直到没有剩下!


章节和诗句:来自sigaction()的POSIX:

  

当信号被安装的信号捕获功能捕获时   sigaction(),计算并安装一个新的信号掩码   信号捕捉功能的持续时间(或直到呼叫任何一个   sigprocmask()或sigsuspend()被创建)。这个面具是通过服用形成的   当前信号掩码的联合和sa_mask的值   正在传递的信号,除非是SA_NODEFER或SA_RESETHAND   设置,然后包括正在传递的信号。如果和当用户的时候   信号处理程序正常返回,恢复原始信号掩码。

答案 1 :(得分:0)

仔细阅读 time(7)signal(7)

信号处理程序可以做很少的事情(它不应该调用,甚至间接调用printfmalloc ...)许多信号处理程序只需设置一个volatile sigatomic_t整数变量,稍后在代码中测试。

我建议根据event loop之类的多路复用系统调用来获得一些poll(2)。您可以使用现有的事件循环框架(例如libevlibeventglib等等)或在poll之上创建自己的事件循环框架。特定于Linux的timerfd_create(2)& signalfd(2)可以提供很多帮助。