exit ()와 abort ()의 차이점은 무엇입니까?


답변:


116

abort()atexit()먼저 사용하여 등록 된 함수를 호출 하지 않고 객체의 소멸자를 먼저 호출 하지 않고 프로그램을 종료합니다 . exit()프로그램을 종료하기 전에 둘 다 수행합니다. 자동 객체에 대해서는 소멸자를 호출하지 않습니다. 그래서

A a;
void test() { 
    static A b;
    A c;
    exit(0);
}

소멸 a되고 b적절하지만의 소멸자를 호출하지 않습니다 c. abort()객체의 소멸자를 호출하지 않습니다. 불행히도 C ++ 표준은 적절한 종료를 보장하는 대체 메커니즘을 설명합니다.

자동 저장 기간이있는 main()객체 는 함수 에 자동 객체가없고 호출을 실행 하는 프로그램에서 모두 파괴 됩니다 exit(). 에 main()잡힌 예외를 발생시켜 제어를 그러한에 직접 전송할 수 있습니다 main().

struct exit_exception { 
   int c; 
   exit_exception(int c):c(c) { } 
};

int main() {
    try {
        // put all code in here
    } catch(exit_exception& e) {
        exit(e.c);
    }
}

을 호출하는 대신 exit()해당 코드 throw exit_exception(exit_code);를 정렬하십시오 .


2
Brian R. Bondy는 훌륭했지만 중단 / 종료 (스택 객체의 소멸자가 아님) 문제를 제기하고 RAII 집약적 C ++ 프로세스에 대한 대안을 제공했기 때문에 +1입니다.
paercebal

나는 dtor를 호출하지 않고 프로그램을 종료하는 방법을 찾고 있었고 당신의 대답은 내가 찾고있는 것입니다! 감사합니다
acemtp

자동 객체 소멸자가 실제로 호출되지 않는 것이 중요하다면 당연히 맞습니다.
Chris Huang-Leaver

내 지식으로는 종료와 중단의 또 다른 차이점은 중단은 운영 체제 구성에 따라 코어 덤프를 생성 할 수 있다는 것입니다.
Dirk Herrmann

33

중단 SIGABRT 신호를 전송, 출구는 단지 일반 정리 작업을 수행하는 응용 프로그램을 닫습니다.

원하는대로 중단 신호를 처리 할 수 있지만 기본 동작은 오류 코드와 함께 응용 프로그램을 닫는 것입니다.

중단 은 정적 및 전역 구성원의 오브젝트 삭제를 수행하지 않지만 종료 됩니다.

물론 응용 프로그램이 완전히 닫히면 운영 체제는 사용 가능한 메모리와 기타 리소스를 비 웁니다.

모두에서 중지종료 프로그램 종료, 리턴 코드는 응용 프로그램을 시작 부모 프로세스로 돌아갑니다 (기본 동작을 재정의하지 않은 가정).

다음 예를 참조하십시오.

SomeClassType someobject;

void myProgramIsTerminating1(void)
{
  cout<<"exit function 1"<<endl;
}

void myProgramIsTerminating2(void)
{
  cout<<"exit function 2"<<endl;
}

int main(int argc, char**argv)
{
  atexit (myProgramIsTerminating1);
  atexit (myProgramIsTerminating2);
  //abort();
  return 0;
}

코멘트:

  • 중단 이 주석 처리되지 않은 경우 : 아무것도 인쇄되지 않으며 어떤 오브젝트의 소멸자가 호출되지 않습니다.

  • 위와 같이 abort 를 주석 처리 하면 someobject 소멸자가 호출되고 다음과 같은 결과가 나타납니다.

종료 기능 2
종료 기능 1


여기서 종료 기능 2 THEN 종료 기능 1을 호출했습니다. gcc 4, Linux 2.6.
strager

1
atexit 매뉴얼 페이지에 "Atexit을 사용하여 등록 된 함수는 역순으로 호출되며 인수는 전달되지 않습니다."
strager

@strager가 맞습니다. atexit에 의해 등록 된 함수는 exit가 호출되거나 main return이있을 때 역순으로 호출됩니다.
Robert Gamble

테스트를 실행하면 전역 인스턴스에 대한 소멸자가 모든 atexit 콜백 후에 호출됩니다.
strager

+1은 OS가 abort () 호출 후에도 할당 된 모든 리소스를 결국 해제 할 것임을 상기시킵니다.
Fingolfin

10

프로그램이 exit()를 호출하면 다음과 같은 일이 발생합니다 .

  • 기능에 의해 등록 된 atexit기능이 실행됩니다
  • 모든 열린 스트림이 플러시되고 닫히고 생성 된 파일 tmpfile이 제거됩니다.
  • 프로그램은 지정된 종료 코드로 호스트에 종료됩니다.

abort() 함수는 전송 SIGABRT이 프로그램이 열린 스트림 / 플러시 종료되었는지 또는 통해 생성 된 임시 파일 것이라는 보장은 종료된다 잡힌하지 않으면 현재 프로세스 신호를 tmpfile제거는, atexit등록 된 함수가 호출되지 않고, 비 종료 상태 0이 호스트로 리턴됩니다.


흠. 표준에 따르면 신호 핸들러가 "돌아 오지 않는"경우에만 프로그램이 종료되지 않습니다. C를 잘 알고 있습니다. 반환하지 않고 정상적인 실행을 계속할 수있는 시나리오를 상상할 수 있습니까? longjmp를 상상하지만 신호 처리기에서 어떻게 작동하는지 잘 모르겠습니다.
Johannes Schaub-litb

일반적으로 신호 처리기에서 longjmp를 호출하는 것은 정의되지 않았지만 신호가 발생 / 중단으로 생성 된 경우에 대한 특별한 경우가 있으므로 이론적으로는 가능하다고 생각하지 않지만 이론적으로는 가능할 것입니다. 이제 시도해 볼 것입니다;)
Robert Gamble

1
이것은 작동하는 것 같습니다 (300 자 제한으로 인해 여러 게시물에 손상됨). jmp_buf env; void abort_handler (int i) {do_abort = 0; longjmp (env, 1);}
Robert Gamble

int main (void) {setjmp (env); puts ( "Asetjmp"); if (do_abort) {signal (SIGABRT, abort_handler); puts ( "호출 중단"); 중단 (); } puts ( "취소하지 않았습니다!"); 리턴 0; }
Robert Gamble

Ubuntu 7.04에서 다음과 같이 인쇄됩니다. setjmp에서 호출 중단 setjmp에서 중단하지 않았습니다!
Robert Gamble

5

exit () 매뉴얼 페이지에서 :

exit () 함수는 정상적인 프로세스 종료를 유발하고 상태 값 & 0377이 상위로 리턴됩니다.

abort () 매뉴얼 페이지에서 :

abort ()는 먼저 SIGABRT 신호를 차단 해제 한 다음 호출 프로세스를 위해 해당 신호를 발생시킵니다. 이로 인해 SIGABRT 신호가 포착되고 신호 핸들러가 리턴되지 않으면 프로세스가 비정상적으로 종료됩니다.


4

abortSIGABRT신호를 보냅니다 . abort발신자에게 돌아 오지 않습니다. SIGABRT신호 의 기본 처리기 는 응용 프로그램을 닫습니다. stdio파일 스트림이 플러시 된 다음 닫힙니다. 그러나 C ++ 클래스 인스턴스의 소멸자는 확실하지 않습니다 (이것에 대해서는 확실하지 않습니다-아마도 결과가 정의되지 않았습니까?).

exit로 설정된 자체 콜백이 atexit있습니다. 콜백이 지정되면 (또는 하나만) 등록 순서와 반대로 (스택과 같은) 순서로 호출되면 프로그램이 종료됩니다. 와 마찬가지로 abort, exit호출자에게 반환하지 않습니다. stdio파일 스트림이 플러시 된 다음 닫힙니다. 또한 C ++ 클래스 인스턴스의 소멸자가 호출됩니다.


exit는 atexit를 통해 여러 개의 콜백 함수를 등록 할 수 있습니다. exit가 호출되면 모든 콜백 함수가 등록 된 역순으로 호출됩니다.
Robert Gamble

@Gamble, 물론, 몇 분 전에 @Bondy의 답변에 대한 의견에서 나 자신을 언급했습니다. 이를 반영하여 내 답변을 편집하겠습니다.
strager
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.