2012-03-03 41 views
5

代碼在第一問題(最小化的情況下):printf的是不是在C信號處理程序工作

#include <stdio.h> 
#include <signal.h> 

int counter = 0; 

void react_to_signal(int n) { 
    fprintf(stderr, "Caught!\n"); 
    counter++; 
} 

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

    signal(SIGINFO, react_to_signal); 

    while (1) { 
     printf("%d\n", counter); 
    } 

    return 0; 
} 

我運行的代碼,它循環,因爲它應該,在另一個殼打印出0。然後..

kill -s SIGINFO <pid_of_my_process> 

信號傳遞,c遞增..但fprintf不會發生。

這是爲什麼?處理程序代碼在什麼環境/上下文中運行?我在哪裏可以讀到這個?

+0

嘗試使用'fflush(stderr)'刷新stderr' – Saphrosit 2012-03-03 17:04:46

+2

不要使用printf()et.al.內部信號處理程序。他們不是信號安全的(例如:可以調用malloc(),這不是信號安全的) – wildplasser 2012-03-03 17:05:35

+0

有趣的是,我可以發誓我在發佈之前曾嘗試過一個帶'fflush'的變體。要麼從不重新編譯並運行,要麼通過無限循環將屏幕上的消息移出腳部。如此無語和愚蠢。 – ntl0ve 2012-03-03 18:43:36

回答

14

簡而言之:你不能用信號處理程序中安全的printf

有信號處理程序男子頁list of authorized functions,在異步信號安全部分。其中沒有fprintf。

那是因爲這個函數不是可重入,主要是因爲它可以使用malloc和free。 有關詳細說明,請參閱this post

+0

好的,現在全部清楚。非常感謝! – ntl0ve 2012-03-03 18:31:48

1

您可能需要在程序退出之前使用stderr來獲取要寫入的消息。

+0

當printf到達換行符時不會自動刷新? – 2017-07-03 23:53:57

+1

編號見https://stackoverflow.com/questions/5229096/does-printf-always-flush-the-buffer-on-encountering-a-newline – 2017-07-04 00:00:53