atexit가 등록한 함수는main 함수 다음에 실행됩니까?
18526 단어 main
The atexit() function registers the given function to be called at normal process termination, either via exit(3) or via return from the program’s main(). Functions so registered are called in the reverse order of their registration; no arguments are passed.
언뜻 보기에는 다음과 같은 인상이 형성되었다. "오,atexit 함수는 함수 A를 등록해서main 함수를 종료한 후에 함수 A를 실행해야 프로세스가 철저하게 오버된다."
작업 중에 잘못된 버그를 만났을 때 로그에서 프로세스가atexit에 등록된 함수를 실행할 때main 함수 안의 라인은 여전히 즐겁게 실행되고 있음을 발견했다. 이런 현상은 나의 이전의 인식을 전복시켜서atexit에 등록된 함수가 도대체 언제 실행되는지 다시 생각해야만 했다."main 함수 종료"란 무엇입니까?
이전 간단한 코드:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <pthread.h>
5
6 void bye(void)
7 {
8 printf("before bye
");
9 sleep(10);
10 printf("after bye
");
11 }
12
13 void *do_thread(void)
14 {
15 while(1)
16 {
17 printf("--------------I'm thread!
");
18 sleep(1);
19 }
20 }
21
22 int main(void)
23 {
24 pthread_t pid_t;
25
26 atexit(bye);
27 pthread_create(&pid_t, NULL, (void *)do_thread, NULL);
28
29 exit(EXIT_SUCCESS);
30 }
위의 프로그램은 먼저atexit로 프로그램이 정상적으로 종료된 후의 실행 함수를 등록한 다음에 정보를 끊임없이 출력하는 데 사용할 라인을 만들고 메인 라인은 exit를 실행한다.
실행 프로그램은 무엇을 출력합니까?
내가 처음에 추측한 운행 결과는 다음과 같다.
before bye
after bye
또는:
--------------I'm thread!
before bye
after bye
내 이해에서bye()는main 함수를 종료한 후에 실행하기 때문에, 그때main 함수에 생성된 라인은 존재하지 않을 것이며, 코드는bye() 함수를 조용히 실행할 것이다.사실이 증명하듯이, 나는 너무 당연하다고 생각한다.
위의 프로그램의 실제 실행 결과는 다음과 같습니다.
1 before bye
2 --------------I'm thread!
3 --------------I'm thread!
4 --------------I'm thread!
5 --------------I'm thread!
6 --------------I'm thread!
7 --------------I'm thread!
8 --------------I'm thread!
9 --------------I'm thread!
10 --------------I'm thread!
11 --------------I'm thread!
12 after bye
왜 bye()를 실행할 때 라인이 아직 있습니까?
exit () 함수의 원본을 보십시오.
1 /* Copyright (C) 1991,95,96,97,99,2001,2002,2005,2009
2 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <sysdep.h>
23 #include "exit.h"
24
25 #include "set-hooks.h"
26 DEFINE_HOOK (__libc_atexit, (void))
27
28
29 /* Call all functions registered with `atexit' and `on_exit',
30 in the reverse of the order in which they were registered
31 perform stdio cleanup, and terminate program execution with STATUS. */
32 void
33 attribute_hidden
34 __run_exit_handlers (int status, struct exit_function_list **listp,
35 bool run_list_atexit)
36 {
37 /* We do it this way to handle recursive calls to exit () made by
38 the functions registered with `atexit' and `on_exit'. We call
39 everyone on the list and use the status value in the last
40 exit (). */
41 while (*listp != NULL)
42 {
43 struct exit_function_list *cur = *listp;
44
45 while (cur->idx > 0)
46 {
47 const struct exit_function *const f =
48 &cur->fns[--cur->idx];
49 switch (f->flavor)
50 {
51 void (*atfct) (void);
52 void (*onfct) (int status, void *arg);
53 void (*cxafct) (void *arg, int status);
54
55 case ef_free:
56 case ef_us:
57 break;
58 case ef_on:
59 onfct = f->func.on.fn;
60 #ifdef PTR_DEMANGLE
61 PTR_DEMANGLE (onfct);
62 #endif
63 onfct (status, f->func.on.arg);
64 break;
65 case ef_at:
66 atfct = f->func.at;
67 #ifdef PTR_DEMANGLE
68 PTR_DEMANGLE (atfct);
69 #endif
70 atfct ();
71 break;
72 case ef_cxa:
73 cxafct = f->func.cxa.fn;
74 #ifdef PTR_DEMANGLE
75 PTR_DEMANGLE (cxafct);
76 #endif
77 cxafct (f->func.cxa.arg, status);
78 break;
79 }
80 }
81
82 *listp = cur->next;
83 if (*listp != NULL)
84 /* Don't free the last element in the chain, this is the statically
85 allocate element. */
86 free (cur);
87 }
88
89 if (run_list_atexit)
90 RUN_HOOK (__libc_atexit, ());
91
92 _exit (status);
93 }
94
95
96 void
97 exit (int status)
98 {
99 __run_exit_handlers (status, &__exit_funcs, true);
100 }
101 libc_hidden_def (exit)
위의 원본 코드에서 알 수 있듯이 exit () 는atexit 등록된 함수를 실행한 다음에 _exit 함수,_exit는 프로세스의 모든 파일 설명자를 닫고 메모리와 다른 내부 핵 정리 함수를 정리합니다.그래서 exit()가 _까지 실행되면exit () 가 있을 때, 이전에 만든 라인이 실행을 중지합니다.이전에 내 머릿속에 존재했던'main 함수 종료'의 개념은 너무 추상적이었다. 그 뒤에 존재하는 것은 사실 하나의 동작 흐름이다.atexit가 등록한 함수를 실행하고 플러그인 흐름(stdin,stdout,stderr)을 갱신하며 파일 버퍼의 내용을 파일로 되돌려주고 프로세스의 모든 파일 설명자를 닫으며 메모리와 다른 내부 청소 함수를 정리한다.exit() 및_exit () 원본은 잘 연구해야 합니다.
다시 한 번 첫 번째 문장의atexit 해석을 돌이켜보면 다른 깊은 뜻이 있다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
C++ 정리 - 10 main 함수모든 C++ 프로그램엔 main함수가 있어야 한다. (Dynamic-link libraries와 static libraries 에는 main함수가 없다) 내 프로그램에서 main함수를 호출할 수 없다. main함수를...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.