'atexit'에 해당되는 글 2건
- 2011.11.03 프로세스의 종료 - exit, _exit, atexit
- 2011.09.03 showtimes - exit핸들러 등록하여 프로그램 CPU 사용률 출력
#include <stdlib.h> /* _exit(2) */ void _exit(int status); return: 없음 #include <unistd.h> /* exit(3) */ void exit(int status); return: 없음 #include <stdlib.h> /* exit(3) */ int atexit(void (*function)(void));
return: 성공 0, 실패 -1 |
◎ _exit()는 호출 프로세스를 "즉시" 종료합니다.
프로세스에 속한 열린 파일 디스크립터들이 모두 닫히고, 프로세스의 자식들은
프로세스 1번인 init프로세스 에게 승계하며 프로세스 부모에게는 SIGCHLD 시그널이 갑니다.
값 status을 부모 프로세스에게 프로세스의 종료 상태로 반환합니다.
(함수 _Exit()는 _exit()과 동등함)
◎ exit()는 일종의 라이브러리로 먼저 표준 입출력 라이브러리들에서 사용한 버퍼를 모두 방출(flush)
시키고 atexit()에서 등록시킨 exit 핸들러들을 모두 실행시킨후 _exit()를 호출하게 된다.
(main()에서의 return()은 exit()와 동등함)
C 표준에서는 두 상수 EXIT_SUCCESS와 EXIT_FAILURE를 명세하고 있는데,
이를 exit()에게 전달해서 각각 성공적인 종료과 성공적이지 못한 종료를 나타낼 수 있습니다.
◎ atexit() 함수는 exit(3)이나 프로그램 main()에서의 반환을 통한 정상적 프로세스 종료시 주어진
함수 function을 호출하도록 등록합니다. 그렇게 등록한 함수들은 등록 역순으로 호출하며 아무
인자도 전달하지 않습니다.
(같은 함수를 여러 번 등록하는 것도 가능. 각 등록마다 한 번씩 호출)
POSIX.1-2001에서는 구현체가 적어도 ATEXIT_MAX (32)개까지의 함수 등록을 허용해야 한다고 요구
하고 있습니다. 구현체가 지원하는 실제 제한치는 sysconf(3)를 이용해 얻을 수 있습니다.
fork(2)를 통해 자식 프로세스가 생기면 부모의 등록 함수들 사본을 물려받습니다.
exec(3)군 함수 중 하나의 호출이 성공하면 등록 항목 모두가 지워집니다.
※(exit 핸들러란, 프로그램 종료 시에 실행시킬 일종의 작업을 일컫는 것으로 atexit()에 의해 등록)
'Linux > Programming' 카테고리의 다른 글
한계들(Limits) – limits.h 와 conf 함수들 (0) | 2011.10.23 |
---|---|
파일 접근 시간과 수정 시간을 변경 - utime(2) (0) | 2011.10.23 |
파일 시간들(File Times) - 수정, 변경, 접근 시간 (0) | 2011.10.23 |
파일 접근 권한 비트 요약 (0) | 2011.10.23 |
파일 상태 정보 얻기 - stat, fstat, and lstat Functions (0) | 2011.10.23 |
C의 atexit 함수는 사용자가 정의한 종료 핸들러를 등록한다.
종료 핸들러는 프로그램이 main 함수로부터 리턴 하거나 exit 함수를 호출하였을 때
마지막에 등록된 핸들러가 먼저 실행되는 순서로 실행. (여러 번 호출하여 핸들러 등록 가능)
♧ showtimes 예제는 showtimes 함수를 exit 핸들러로 등록하여
프로그램과 그 자식들이 사용한 시간에 대한 통계를 표준 에러로 출력한다.
[ 예제 코드 : showtimes.c ] |
#include <limits.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/times.h> #include <sys/wait.h> int wastetime(int maxus); static void showtimes(void) { double ticks; struct tms tinfo; if ((ticks = (double) sysconf(_SC_CLK_TCK)) == -1) perror("Failed to determine clock ticks per second"); else if (times(&tinfo) == (clock_t)-1) perror("Failed to get times information"); else { fprintf(stderr, "User time: %8.3f seconds\n", tinfo.tms_utime/ticks); fprintf(stderr, "System time: %8.3f seconds\n", tinfo.tms_stime/ticks); fprintf(stderr, "Children's user time: %8.3f seconds\n", tinfo.tms_cutime/ticks); fprintf(stderr, "Children's system time: %8.3f seconds\n", tinfo.tms_cstime/ticks); } } int main(void) { if (atexit(showtimes)) { fprintf(stderr, "Failed to install showtimes exit handler\n"); return 1; } if (fork()) wastetime(2900000); else wastetime(5400000); if (wait(NULL) > 0) fprintf(stderr, "\nChild has exited, parent stats follow:\n"); return 0; } |
☞ times 함수는 시간 틱(tick) 수의 시간 정보를 나타낸다.
[ 예제 코드 : wastetime.c ] |
#include <stdio.h> #include <sys/time.h> #define MILLION 1000000L /* waste maxus microseconds of time */ int wastetime(int maxus) { long timedif; struct timeval tp1, tp2; if (gettimeofday(&tp1, NULL)) { fprintf(stderr, "Failed to get initial time\n"); return 1; } timedif = 0; while (timedif < maxus) { if (gettimeofday(&tp2, NULL)) { fprintf(stderr, "Failed to get check time\n"); return 1; } timedif = MILLION*(tp2.tv_sec - tp1.tv_sec) + tp2.tv_usec - tp1.tv_usec; if (timedif < 0) break; } return 0; } |
▶ 사용 예:
$ ./showtimes User time: 1.270 seconds System time: 2.660 seconds Children's user time: 0.000 seconds Children's system time: 0.000 seconds
Child has exited, parent stats follow: User time: 0.460 seconds System time: 0.970 seconds Children's user time: 1.270 seconds Children's system time: 2.660 seconds |
'예제 코드 & 코드 조각' 카테고리의 다른 글
[string.c] strcat, strcpy, strcmp, strlen (1) | 2011.10.14 |
---|---|
재시작 라이브러리 (restart library) (0) | 2011.09.03 |
keeplog - 리스트 자료 구조를 사용하여 커맨드 실행 기록 저장 (0) | 2011.09.02 |
wordaverage - 한 줄 평균 단어 구하기 (0) | 2011.09.02 |
makeargv - 인자 배열 만들기 (0) | 2011.09.02 |