进程的100种退出方式
1. 从main 函数 return 时,首先析构自动变量 (按照与声明顺序相反的顺序来析构), 然后执行全局和静态变量的析构,以及注册的 atexit 函数,顺序与声明顺序相反。
A a1;
比如 int main() {
A a2;
ateixt(fun1);
static A a3;
return 0;
}
那么函数执行顺序为
a2.~A() --> a3.~A() --> fun1 --> a1.~A()
2. exit(0) 退出, 注意这里并不会执行自动变量的析构函数,但是静态声明周期变量的析构函数和 atexit 注册的函数都会执行
3. _exit(0) _Exit(0) abort()
这三个都是直接结束程序,什么回收工作都不做,前两个是等价的,第三个会保存一份core dump
注意,以上都是结束整个进程的方法,所以一旦触发其中任何一个,所有的线程都会停止
4. 最后一个调用 pthread_exit 线程
pthread_exit 是否会析构局部变量是由实现决定的,我们应该假设它并不会执行析构函数。如果进程是以 “最后一个线程调用pthread_exit”这种方式结束的,
那么操作系统会自动帮我们调用一次exit(0),并且一定是0,而不是其他的东西。
5 关于pthread_cleanup_push, pthread_cleanup_pop,线程特有数据
首先线程在phtread_cleanup_push 和 phread_clean_pop 之间调用pthread_exit时,会以相反顺序调用未 pop 的函数,如果使用
return 而不用 pthread_exit 的话很可能直接挂了。。至少是决不会调用未pop的函数的。
之后按照任意顺序析构线程特有数据
6 C++11 中的thread_local
这个可以修饰全局变量,也可以修饰static变量。
它的初始化时机就是以线程视角第一次遇见它之前,比如进入线程执行函数之前执行全局thread_local的初始化,第一次遇见static thread_local 之前进行
它的初始化,销毁时机就是离开线程执行函数之后,在该线程销毁
即 thread_local 的创建和销毁都在新创建的线程里执行(mac os , g++-5)
浙公网安备 33010602011771号