2012-08-27 3 views
4

나는이 프로그램을 유닉스 환경의 어드밴스 프로그래밍에서 시도했다.왜 신호 처리시 콘솔에 출력이 없습니까?

#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; 
} 

저는 우분투 11.10을 사용하고 있습니다. gcc로 프로그램을 컴파일 한 다음 책에 표시된대로 a.out을 실행합니다.

$./ [1] + 1,345

-USR1 $ 1,345

죽 그러나 인쇄 출력 금지가없는 &의 a.out. 이 프로그램은 backgound에서 실행을 계속하고 그것을 죽여야 만합니다. 내가 시도

다른 것들 :

  1. 백그라운드에서 프로그램을 실행하는 문제의 원인이 있는지 확인하기 위해 SIGINT를 처리했습니다. 아직 출력이 없습니다.

  2. 최신 릴리스의 FreeBSD를 다운로드하여 동일한 프로그램을 시도했지만 동일한 문제가 있습니다.

  3. 내가 신호 처리기를 설정하기 전에의 printf 문을 넣어 :

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

, 아무런 출력이 없습니다. 주석 처리를 제거하면 출력이 인쇄됩니다.

내가 뭘 잘못하고 있는지 말해줘?

추 신 : sigaction()을 사용하지 마십시오. 실용적인 응용 프로그램을 만들지 않고 유닉스 프로그래밍을 배우고 있습니다.

+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' :-) * 리눅스 프로그램을 심각하게 생각하게 만듭니다. –

답변

9

printf의 출력이 버퍼링됩니다. 즉 출력으로 플러시 될 때까지 메모리에 저장됩니다. printf에서 텍스트를 플러시하는 가장 좋은 방법은 텍스트를 개행 문자로 끝내는 것입니다. fflush 기능을 사용하여 수동으로 플러시 할 수도 있습니다.

그러나 printffflush과 같은 출력 기능을 사용하면 신호 처리기에서 안전하지 않은 것으로 간주되므로주의해야합니다.

+0

은 매력처럼 작동 ... 도움 주셔서 감사합니다 ... :) –

+0

예, 그들은 재진입 기능이 아닙니다. 하지만, 나는 단지 그들을 학습 목적으로 사용하고 있습니다. –

+0

학습은 신호 처리기에서 안전하지 않은 기능을 사용하지 않는 법을 배우는 가장 좋은시기입니다. 안전한 함수 목록은 http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html에서 구할 수 있습니다. 단지'printf/fflush' 대신에'write'를 사용하십시오. –

관련 문제