2014-01-11 1 views
0

C에서 매우 간단한 프로그램 실행 타이머를 만들고 있습니다. 아래 샘플 코드를 제공 할 것입니다. 문제는 Ctrl + C (즉, SIGINT 신호)로 프로그램을 종료 할 때 stdout에서 "Hello World\n"을 모두 플러시하지 않는다는 것입니다. 그들은 때로는 Estimated running time... 메시지 이후에 나타납니다. 왜 그런지 궁금합니다.fflush()가 제대로 플러시되지 않습니다.

타이머 .c

#include <signal.h> 
#include <time.h> 
#include <errno.h> 
#include <stdlib.h> 
#include <stdio.h> 

#define _TIMER 
#include "timer.h" 

static clock_t startTime; 

int installTimer(void) 
{ 
    errno = 0; 
    if (signal(SIGINT, signalHandler) == SIG_ERR || 
     signal(SIGTERM, signalHandler) == SIG_ERR || 
     signal(SIGABRT, signalHandler) == SIG_ERR) 
     return 1; 
    if (atexit(displayTimer)) 
     return 1; 
    if ((startTime = clock()) == -1) 
     return 1; 
    return 0; 
} 

static void displayTimer() 
{ 
    clock_t endTime; 
    if ((endTime = clock()) == -1) 
     printf("ERROR: clock() failed.\n"); 
    else 
     printf("Estimated running time: %.4fs\n", (endTime - startTime)/(double) CLOCKS_PER_SEC); 
} 

static void signalHandler(int signal) 
{ 
    fflush(NULL); 
    exit(EXIT_FAILURE); 
} 

Timer.h :

int installTimer(void); 

#ifdef _TIMER 
    static void displayTimer(void); 
    static void signalHandler(int); 
#endif 

timerTest.c

#include <stdio.h> 
#include "timer.h" 

int main(void) 
{ 
    if (installTimer()) 
    { 
     printf("ERROR: installTimer() failed.\n"); 
     return 1; 
    } 
    int i; 
    for (i = 0; i < 300000; ++i) 
     printf("Hello World!\n"); 
    return 0; 
} 

답변

3

여러분의 프로그램은 정의되지 않은 동작을 호출합니다. 신호 처리기에는 fflush()으로 전화 할 수 없습니다. 일반적으로 신호 처리기 내부에서 IO 라이브러리 함수를 호출하는 것은 좋지 않습니다.

엄격하게 부합하는 프로그램은 신호 처리기 내에서 C 표준 라이브러리 함수 abort(), _Exit(), quick_exit()signal() 만 호출 할 수 있습니다.

즉, fflush()은 비동기 안전하지 않으므로 시도하지 마십시오. 가능한 해결 방법과 링크 I need a list of Async-Signal-Safe Functions from glibc

그 질문 포인트 :

더 자세한 내용은이 질문을 참조하십시오.

+0

감사합니다.하지만 Windows 용 비동기 신호 안전 기능 목록도 갖고 있습니까? – Jori

+0

또한 올바르게 이해했다면'fflush()'가 async-signal-safe가 아니기 때문에 프로그램의 마지막에 예상 시간 메시지를 출력 할 방법이 없다. (printf 대신'write' Windows에서 안전하다면). – Jori

+0

흠, 나는 정직하게 여기에서 갈 것입니다. Windows의 경우, 나는 잘 모릅니다. Windows POSIX 구현을 설치 한 다음 비동기 안전 기능을 위해 POSIX 목록을 사용할 수 있습니다. 그렇지 않으면 특정 문서를 읽는 것이 좋습니다. 나는 보통 윈도우 용으로 개발하지 않기 때문에 나는 그 세계에서 벗어났다. 두 번째 질문에 대해서는 예를 들어'쓰기 '와 같은 안전한 호출로 처리해야합니다. –