2012-08-27 142 views
4

我正在從Unix環境下的Advance Programming中嘗試這個程序。爲什麼控制檯上的信號處理沒有輸出?

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

static void handler(int sig){ 
    if(sig == SIGUSR1) 
     printf("handled user1 signal"); 
    else if(sig == SIGUSR2) 
     printf("handles user2 signal"); 
    else 
     printf("unkown signal"); 
} 

int main(){ 

    if(signal(SIGUSR1, handler) == SIG_ERR) 
     printf("can't handle signal SIGUSR1"); 
    if(signal(SIGUSR2, handler) == SIG_ERR) 
     printf("can't handle signal SIGUSR2"); 
    for(;;) 
     pause(); 
    return 0; 
} 

我使用的是Ubuntu 11.10。我使用gcc編譯程序,然後按照書中的說明運行a.out。

$。/ a.out的& [1] + 1345

$殺-USR1 1345

但沒有輸出打印。程序一直在後臺運行,我必須殺死它。

其他的事情我已經嘗試:

  1. 試圖處理SIGINT,看是否在後臺運行的程序導致的問題。仍然沒有輸出。

  2. 下載了FreeBSD的最新版本,並嘗試使用相同的程序,但遇到同樣的問題。

  3. 我把printf語句設定信號處理程序之前:

    int main(){ 
        printf("printf is working..."); 
        //exit(0); 
        if(signal(SIGUSR1, handler) == SIG_ERR) 
        ... 
    

時exit()時評論說,沒有輸出。當我取消註釋時,輸出被打印。

請告訴我我在這做錯了什麼? PS:不建議使用sigaction()。我正在學習Unix編程,而不是構建任何實際的應用程序。

+4

懷疑您需要刷新標準輸出緩衝區。然而,在信號處理程序中可以做些什麼是有限制的(我會嘗試找到有人給我的鏈接詳細說明)。 – hmjd

+0

這裏是:https://www.securecoding.cert.org/confluence/display/seccode/SIG30-C.+Call+only+asynchronous-safe+functions+within+signal+handlers – hmjd

+0

適當的建議不是'sigaction()',而是'signalfd'和'epoll' :-) *這會讓你在Linux編程中變得認真。 –

回答

9

printf的輸出被緩衝。這意味着它被存儲在內存中,直到刷新到輸出。在printf中刷新文本的最佳方式是用換行符結束文本。您也可以使用fflush功能手動沖洗。

但是,您應該注意,使用輸出函數如printffflush在信號處理程序中不被視爲安全。

+0

工作就像魅力...感謝您的幫助... :) –

+0

是的我知道,他們不是可重入函數。但是,我只是將它們用於學習目的。 –

+0

學習是學習在信號處理程序中不使用不安全函數的最佳時機。安全功能列表可在http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html使用'write'而不是'printf/fflush'。 –