iOS終止函數exit

來源:互聯網
上載者:User

標籤:

1.   exit函數

C,C++函數exit用來終止當前程式, 函數定義如下:


  1. void exit (int status);  


官方說明如下:

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如下:

[html] view plaincopy
  1. thread_local Object obj;  //Object為C++類  
  2. thread_local int value = 1;  


第二點:static storage指的是全域或者函數中static方式定義的變數, 該部分變數會儲存到靜態儲存區(區別於heap和stack), 比如: [html] view plaincopy
  1. Object gObj;  
  2.   
  3. void fun(){  
  4.   
  5.   static Object sObj;  
  6.   
  7. }  
atexit設定的函數在exit過程中會被調用, atexit函數定義如下: [html] view plaincopy
  1. int atexit (void (*func)(void));  

atexit例子如下: [cpp] view plaincopy
  1. /* atexit example */  
  2. #include <stdio.h>      /* puts */  
  3. #include <stdlib.h>     /* atexit */  
  4.   
  5. void fnExit1 (void)  
  6. {  
  7.   puts ("Exit function 1.");  
  8. }  
  9.   
  10. void fnExit2 (void)  
  11. {  
  12.   puts ("Exit function 2.");  
  13. }  
  14.   
  15. int main ()  
  16. {  
  17.   atexit (fnExit1);  
  18.   atexit (fnExit2);  
  19.   puts ("Main function.");  
  20.   exit(0);  
  21. }  

輸出為: [html] view plaincopy
  1. Main function.  
  2. Exit function 2.  
  3. Exit function 1.  


對C++ object銷毀順序, 可以看以下例子: [cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <unistd.h>  
  4. #include <thread>  
  5. #include <string>  
  6. #include <iostream>  
  7.   
  8. class MyObject  
  9. {  
  10. public:  
  11.     std::string str;  
  12. public:  
  13.     MyObject(std::string str){  
  14.         this->str = str;  
  15.     }  
  16.       
  17.     ~MyObject(){  
  18.         printf("%s -- %s\n", __FUNCTION__, str.c_str());  
  19.     }  
  20. };  
  21.   
  22.   
  23. void thread_fun(int n)  
  24. {  
  25.     thread_local MyObject threadObj("thread_local subthread  obj");  
  26.     //do something  
  27.     sleep(2);  
  28. }  
  29.   
  30. void exit_fun(){  
  31.     MyObject threadObj("atexit obj");  
  32.     //do something  
  33.     sleep(1);  
  34. }  
  35.   
  36. MyObject obj("global obj");  
  37. int main(int argc, const char * argv[])  
  38. {  
  39.     thread_local MyObject threadObj("thread_local mainthread  obj");  
  40.     static MyObject staticObj("fun static obj");  
  41.     std::thread t(thread_fun, 1);  
  42.     atexit(exit_fun);  
  43.       
  44.     sleep(2);  
  45.     exit(0);  
  46. }  

輸出: [cpp] view plaincopy
  1. ~MyObject -- thread_local subthread  obj   
  2. ~MyObject -- thread_local mainthread  obj  
  3. ~MyObject -- atexit obj  
  4. ~MyObject -- fun static obj  
  5. ~MyObject -- global obj  
  6. Program ended with exit code: 0  

從上面可以看出, 對於第二點是先調用atexit, 再清理static storage

2. exit vs abort
void abort (void);

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過程銷毀對象而出現非預期結果比如: [html] view plaincopy
  1. MyObject gObj("global obj");  
  2. // ------>  
  3. 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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.