Wednesday, April 2, 2008

Process : Termination - Ways to exit

프로세스의 종료는 간단하다.

#include <stdlib.h>
void exit (int status);

status에 0 혹은 EXIT_SUCCESS를 주면 성공이고, EXIT_FAILURE나 그외 값을 주면 에러로 종료된 것이다. exit()은 atexit()을 통해 등록된 함수들을 (스택에서 pop하듯이) 등록된 역순으로 실행시켜준 후 종료한다. exit()은 프로세스 종료를 위해 여러가지 일들을 하고 내부적으로 다시 _exit()을 실행한다. return 0;으로 main 함수를 끝내도 system call은 호출된다. 컴파일러가 종료시점에 _exit()을 호출하도록 코드를 삽입한다. (vfork()를 사용한 경우 _exit()을 써야한다. exit()는 안되...) 프로세스는 종료할 때 아래 일들을 한다.

  • atexit()에 등록된 함수들을 실행한다.

  • 열려있던 I/O를 닫는다.

  • tmpfile()로 마는 파일들을 삭제한다.


atexit()은 아래와 같이 생겼다.

#include <stdlib.h>
int atexit(void (*function)(void));

등록할 수 있는 함수 갯수는 대략 32개 정도 인데, 정확한 값은 sysconf(_SC_ATEXIT_MAX)를 통해 알 수 있다. 간단한 예를 만들어 볼까...

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

void t1(void) {
printf("exit sub-function 1\n");
}
void t2(void) {
printf("exit sub-function 2\n");
}
int main() {
if (atexit(t1)) fprintf (stderr, "atexit() failed\n");
if (atexit(t2)) fprintf (stderr, "atexit() failed\n");

return 0; // or exit(0);
}

역시 등록한 역순으로 실행된다.

> gcc atexit.c
> ./a.out
exit sub-function 2
exit sub-function 1

exec을 사용하면 atexit()으로 등록한 함수들은 없어지고, 시그널을 받아 종료된 경우에는 이 함수들은 실행되지 않는다.

그외의 방법으로 프로세스가 종료되는 경우에는 SIGTERM, SIGKILL 등의 시그널을 받거나, 메모리 부족, segmentation fault 등으로 커널이 죽이는 경우이다.

1 comment:

  1. Sun OS의 경우 인자값 까지 넘겨줄 수 있는 on_exit()을 사용했으나, 최근에는 사용하지 않는다.

    ReplyDelete