2013-08-19 2 views
2

출력 손실을 피하기 위해 abort()을 호출하기 전에 출력 스트림을 명시 적으로 플러시 할 필요가 있습니까? stderrC/C++ : 비정상 종료 전에 출력 플러시

내가 알고있는 것처럼

, 그래서 확인을해야 stderr/cerr에 출력 한 후 abort를 호출, 버퍼링이 없습니다. 약 stdout/cout 또는 내가 열어 본 파일은 어떻습니까?

추신. 리눅스 환경에서 일하고 있습니다 (중요하다면).

답변

8

예, 필요하지만 불가능할 수도 있습니다. 비동기 신호 컨텍스트에서 중단하는 경우 fflush을 호출하면 정의되지 않은 동작이 호출됩니다. 그리고 일반적으로 abort을 호출하는 이유는 프로그램에서 일관성없는 상태를 감지했기 때문에 stdio 상태가 손상 될 위험이 있으며 따라서 fflush 호출이 안전하지 않을 수 있습니다. 일반적으로

, 당신이 당신의 프로그램을 간단하게 처리 할 수없는 상태로 인해 종료하는 경우 exit(1)를 사용하고, 프로그램이,

이미 정의되지 않은 동작을 호출을 감지 한 경우에만 ( fflush없이) abort()를 사용한다

좀 더 세부 정보 :

표준 가 중단의 일부 (C11 7.22.4.1 :)으로 표준 입출력 스트림을 플러시 구현을 허용하는 C :

버퍼링되지 않은 데이터가있는 열린 스트림이 플러시되는지, 열린 스트림이 닫혀 있는지 또는 임시 파일이 제거되는지 여부는 구현 정의입니다.

그러나 이것은 신호 처리기에서 호출 할 경우 abort이 작동해야한다는 요구 사항을 제거하지 않습니다. 실용적인 견지에서 버퍼가 일치하지 않는 stdio 코드를 인터럽트 한 신호 처리기에서 abort을 호출하면 버퍼를 플러시 할 수 없으므로이 허용치를 사용하려는 구현은 버그가 발생할 가능성이 큽니다.

abort의 리눅스 man 페이지의 현재 버전은 잘못 상태 :

강제 종료() 함수는 프로세스 종료가 발생하면

은 열려있는 모든 스트림이 닫힌다.

현재 동작에 대한보다 정확한 문

는 플러싱 을 시도했지만 데이터를 실패하거나 손상 할 수 있음을 것이다. 이 버그는 (... 아마 수정이 이미 커밋?)의 glibc에 고정되는 과정에서 현재입니다이 스레드에 따라 :이 사실이지만

http://www.sourceware.org/ml/libc-alpha/2013-05/msg00207.html

+0

커널 버퍼 만 플러시하거나 사용자 공간의 stdio 버퍼를 중단하지 않습니까? – user2052436

+0

나는 과학적 코드를 MPI와 OpenMP 쓰레드로 작성하고있다. 그리고 오류 (일반적으로 사용자 입력 관련 또는 일부 런타임 계산 관련)가 발생하면 프로그램을 종료하고 싶습니다. 내가 처음 질문을하는 이유는 프로그램이 종료되기 전에 정보와 오류를 포함하고있는 로그 파일을 비울 필요가 있기 때문이다. 답은 다음과 같습니다.'abort'를 사용할 필요가 없습니다.'exit (EXIT_FAILURE)'로 충분합니까? – user2052436

+0

@ user2052436 : 관찰 가능한 행동으로는 커널 버퍼 같은 것이 없습니다. –

0

표준 출력은 버퍼링되어 있으므로 예를 들어 ofstream으로 여는 파일도 버퍼링됩니다. 플러쉬 조작자를 사용하여 명시 적으로 플러시해야합니다.

+0

대부분의 시간, 그것은 가능한 _is_ 버퍼링을하지 않고 파일을 열면, 어떤 속임수로 버퍼되지 않은'stdout'을 얻을 수도 있다고 생각합니다. – arne

+1

[일부 트릭] (http://en.cppreference.com/w/cpp/io/manip/unitbuf). – BoBTFish

+1

'main'의 시작 부분에'setvbuf' 또는'setbuf'를 사용하면 버퍼링되지 않은'stdout'을 얻을 수 있습니다. –

관련 문제