簡體   English   中英

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

[英]How to generate same signal (SIGALRM) again and again?

我們正在嘗試使用 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;
}

當一個信號被傳遞時,它會被自動屏蔽,直到動作函數返回。

一般來說,你希望你的信號動作函數做到絕對最小值。 您編寫的實際上是一個遞歸操作函數,其中包含您的大部分程序。 即使它確實有效,你也會吃堆棧直到沒有剩下!


章節和詩句:來自sigaction() for POSIX:

當信號被 sigaction() 安裝的信號捕獲函數捕獲時,會在信號捕獲函數的持續時間內計算並安裝新的信號掩碼(或直到調用 sigprocmask() 或 sigsuspend() )。 該掩碼是通過將當前信號掩碼和正在傳遞的信號的 sa_mask 值結合起來形成的,除非設置了 SA_NODEFER 或 SA_RESETHAND,否則包括正在傳遞的信號。 如果並且當用戶的信號處理程序正常返回時,將恢復原始信號掩碼。

仔細閱讀時間(7)信號(7)信號安全(7)

信號處理程序可以做的事情很少(它不應該調用,即使是間接調用printfmalloc ...)許多信號處理程序只是設置一個volatile sigatomic_t整數變量,稍后在代碼中進行測試。

我建議有一些基於一些多路復用系統調用的事件循環,比如poll(2) 您可以使用現有的事件循環框架(如libevlibeventglib等...)或在poll之上制作自己的。 Linux 特定的timerfd_create(2)signalfd(2)可以提供很多幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM