2015-10-24 38 views
3

可以保證C中的信號調用順序嗎?讓我們來看看下面的代碼:C中的信號控制

//main.c 
int counter; 
pid_t pid; 

void alrm_handler(int s) 
{ 
    kill(pid, SIGUSR1); 
    alarm(1); 
    --counter; 
    if (counter == 0) 
     kill(pid, SIGTERM); 
    printf("%d\n", counter); 
    fflush(stdout); 
} 

int main(int argc, char* argv[]) 
{ 
    counter = atoi(argv[1]); 
    signal(SIGALRM, alrm_handler); 
    alarm(1); 

    pid = fork(); 
    if (!pid) 
     execl("child", "child", NULL); 

    wait(NULL); 

    return 0; 
} 

//child.c 
void usr1_handler(int s) 
{ 
    puts("TEXT"); 
    fflush(stdout); 
} 

int main() 
{ 
    signal(SIGUSR1, usr1_handler); 

    while(1) 
    { 
     struct timespec T; 
     T.tv_nsec = 100; 
     T.tv_sec = 0; 
     nanosleep(&T, NULL); 
    } 

    return 0; 
} 

即使我送SIG_USR1 3次,我得到一個輸出只有2次。看起來SIGTERM具有更高的優先級或某些東西。在這種情況下如何實現3個輸出?

+0

發佈的代碼實現了嵌套/遞歸信號處理程序這是一個禁忌。發佈的代碼實現了對I/O函數'printf()的調用'這是一個禁忌。第一個發佈的代碼不正確地處理fork()返回的值,並且似乎期望對execl()的調用永遠不會失敗。 – user3629249

+0

我不是在問這段代碼有什麼錯誤(爲簡單起見,我省略了一些事情)。我所要求的是確保sigterm在sigusr1之前不會到達的一種方法。我認爲這不總是可能的。 SIGTERM的優先級可能高於SIGUSR1,這就是爲什麼他們按照這個順序到達的原因。 – greenshade

+0

本網站的大部分程序員都是'新人',不會從辣椒中得知'錯誤。所以我試圖說明實際問題範圍之外的編碼問題,所以'新'程序員可以學習 – user3629249

回答

2

公開組基本規範問題6 IEEE標準1003.1,2004年版:

未指定將多個同時處於 範圍SIGRTMIN至SIGRTMAX之外的多個同時未決信號傳遞給 進程或被 進程接受的順序。

你的父進程跑這麼快,它可能將SIGUSR1SIGTERM孩子,然後才能接受它,所以孩子有兩個掛起信號和順序是不確定的(閱讀實現定義 - 任何順序可能)。