2012-08-27 84 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'。 –