일반적으로 프로세스를 종료할 때 return문을 사용합니다. 그리고 exit()함수를 사용하기도 합니다.

return 문과 exit() 함수를 사용하는 것은 시스템 입장에서 보았을 때 동일합니다.


#include <stdlib.h>

void exit(int status); 


int main()
{
    printf("This is test code\n");

    return 0;  // exit(0);과 동일
}


exit() 함수 외에도 _exit() 함수와 _Exit() 함수가 있습니다. 이 둘 함수가 exit() 함수와 다른점은 exit()함수는 atexit() 함수로 등록한 종료 핸들러가 있다면 이 핸들러를 모두 처리하고, 표준 입출력 스트림을 닫는 작업을 수행한 후 커널의 종료 작업을 실행하지만 _exit(), _Exit() 함수는 바로 커널에서 종료작업을 실행한다는 것입니다.

커널 종료 작업이라고 하면 프로세스가 사용하던 메모리를 해제하고 열어놓았던 파일의 descriptor등 을 닫는 작업 등 을 말합니다.

유닉스 계열 시스템에서 _exit() 함수와 _Exit() 함수는 같은 함수라고 생각해도 좋습니다.


#include <stdlib.h>

void _Exit(int status);

#include <unistd.h>

void _exit(int status); 


return문을 사용하던 exit(), _exit(), _Exit() 함수를 사용하던 프로세스의 종료 상태를 함수의 인자로 지정하게 됩니다. 

이 인자는 종료 상태를 부모 프로세스에게 알려줄 수 있는 값입니다.


아래 예제에서 사용된 exit() 함수에 들어 있는 인자 -1과 0 값은 부모 프로세스에게 종료 상태를 알려줄 수 있는 값이 됩니다.

부모 프로세스는 자식 프로세스의 종료 상태 값을 얻어서 자식 프로세스가 어떤 상태로 종료 되었는지를 알 수 있는 것입니다. 

#include <stdio.h>
#include <stdlib.h>

float divide(int a, int b)
{
    if(b == 0) {  
        return -1; // 0으로 나누는 것은 에러!
    }
    
    return a/b;
}

int main()
{
    float ret = 0;
    
    ret = divide(10,5);
    if(ret == -1) { 
        printf("Error!\n");
        exit(-1); // 0으로 나누기 시도
    }
    
    printf("ret : = %f\n", ret);
    
    ret = divide(10,0);
    if(ret == -1) {  
        printf("Error!\n");
        exit(-1); // 0으로 나누기 시도
    }
    
    printf("ret : = %f\n", ret);

    exit(0);
}


하지만 자식 프로세스가 비정상적으로 종료되었을 경우에는 커널에서 비정상 종료 상태를 별도로 설정하게 됩니다.

부모 프로세스는 자식의 종료 상태(정상/비정상)를 wait() 함수 또는 waitpid() 함수로 얻을 수 있습니다.


wait() 함수 포스팅에서 자식 프로세스가 정상/비정상적으로 종료되었을 때 부모 프로세스가 어떻게 상태를 얻어 오는지 좀더 자세히 살펴 보도록 하겠습니다.


+ Recent posts