标签:
1. exit函数
C,C++函数exit用来终止当前程序, 函数定义如下:
官方说明如下:
Terminates the process normally, performing the regular cleanup for terminating programs.
Normal program termination performs the following (in the same order):
- Objects associated with the current thread with thread storage duration are destroyed (C++11 only).
- Objects with static storage duration are destroyed (C++) and functions registered withatexit are called.
- All C streams (open with functions in <cstudio>) are closed (and flushed, if buffered), and all files created with tmpfile are removed.
- Control is returned to the host environment.
第三第四点比较容易理解就不展开讨论
第一点:
这里的thread storage指的是线程局部存储, 在线程作用域有效, c++11定义thread storage如下:
- thread_local Object obj; //Object为C++类
- thread_local int value = 1;
第二点:
static storage指的是全局或者函数中static方式定义的变量, 该部分变量会存储到静态存储区(区别于heap和stack), 比如:
- Object gObj;
-
- void fun(){
-
- static Object sObj;
-
- }
atexit设置的函数在exit过程中会被调用, atexit函数定义如下:
- int atexit (void (*func)(void));
atexit例子如下:
-
- #include <stdio.h> /* puts */
- #include <stdlib.h> /* atexit */
-
- void fnExit1 (void)
- {
- puts ("Exit function 1.");
- }
-
- void fnExit2 (void)
- {
- puts ("Exit function 2.");
- }
-
- int main ()
- {
- atexit (fnExit1);
- atexit (fnExit2);
- puts ("Main function.");
- exit(0);
- }
输出为:
- Main function.
- Exit function 2.
- Exit function 1.
对C++ object销毁顺序, 可以看以下例子:
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <thread>
- #include <string>
- #include <iostream>
-
- class MyObject
- {
- public:
- std::string str;
- public:
- MyObject(std::string str){
- this->str = str;
- }
-
- ~MyObject(){
- printf("%s -- %s\n", __FUNCTION__, str.c_str());
- }
- };
-
-
- void thread_fun(int n)
- {
- thread_local MyObject threadObj("thread_local subthread obj");
-
- sleep(2);
- }
-
- void exit_fun(){
- MyObject threadObj("atexit obj");
-
- sleep(1);
- }
-
- MyObject obj("global obj");
- int main(int argc, const char * argv[])
- {
- thread_local MyObject threadObj("thread_local mainthread obj");
- static MyObject staticObj("fun static obj");
- std::thread t(thread_fun, 1);
- atexit(exit_fun);
-
- sleep(2);
- exit(0);
- }
输出:
- ~MyObject -- thread_local subthread obj
- ~MyObject -- thread_local mainthread obj
- ~MyObject -- atexit obj
- ~MyObject -- fun static obj
- ~MyObject -- global obj
- Program ended with exit code: 0
从上面可以看出, 对于第二点是先调用atexit, 再清理static storage
2. exit vs abort
abort函数实际上是发送SIGABRT signal, 如果不处理则直接终止程序,此时并不会做cleanup操作,相当于直接终止程序。
3. IOS exit函数
双击Home 手动kill掉程序, 会调用exit函数关闭程序, __cxa_finalize函数会执行上面讲到清理工作。
如果重载了AppDelegate applicationWillTerminate函数,则在执行exit之前会调用该函数,终止前提供开发者程序处理机会。
如果程序已经退到后台并处于suspend状态, 这时手动kill并不会按照上面方式调用exit, 而是发送SIGKILL signal, 直接终止程序。
4. exit和多线程
当exit被调用时, 如果其它线程正在执行并且访问了 global或者staic c++ object对象时, 则可能由于这些对象已被销毁而出现无法预期的内存错误,比如:SIGBUS,SIGSEGV。 如需避免该问题可以有以下一些处理方案:
1). 把对象从static storage移动heap上, 避免exit过程销毁对象而出现非预期结果
比如:
- MyObject gObj("global obj");
- // ------>
- MyObject* pObj = new MyObject("global obj ptr");
2). 通过atexit注册回调, 或者applicationWillTerminate(iOS) 中结束子线程避免引用可能销毁的对象。
5. iOS上终止程序
1). 主动调用exit或用户终止(程序未进入suspend状态,applicationDidEnterBackground未回调)
在iOS上可以直接调用exit(0)终止程序,也会按照上面说到的cleanup清理c++ object. (注:iOS 7.0模拟器未做清理,iPhone和7.1模拟器都ok, 估计是模拟器bug)
2). 如果程序已经进入suspend状态 applicationDidEnterBackground已经回调,则系统会直接发送SIGKILL强制程序直接结束
iOS终止函数exit
标签:
原文地址:http://blog.csdn.net/shuju345/article/details/47664145