exit(),_exit(),_Exit()

關於exit(),_exit(),_Exit()


author: i.sshe
email: [email protected]
github: https://github.com/isshe


  1. 綜述: _exit()和_Exit()立即進入內核,exit()則先執行一些清理處理,然後返回內核.
    1). exit(): 正常終止進程。所有atexit()和on_exit()註冊的處理函數都會被反序調用.總會執行一個標準I/O庫的清理關閉操作:對所有打開流調用fclose()函數.。
    2). _exit()/_Exit(): 立刻(immediately)終止進程。不進行終止處理。
  2. 函數原型
    1).exit(): statue&0377的值(狀態)返回給父進程。(注意exit()是沒有返回值的)

        #include <stdlib.h>
        void exit(int status);

    2)._exit()/_Exit():

       #include <unistd.h>
       void _exit(int status);
       #include <stdlib.h>
       void _Exit(int status);
  3. 圖示:一個C程序是如何啓動和終止的
    這裏寫圖片描述

4. exit()/_exit()/_Exit()
 1).示例代碼:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(void)
{
     pid_t  p1 ;
     pid_t  p2 ;

     p1 = fork();
     if (p1 == 0)
     {
          printf("_exit()1!\n");
          printf("_exit()2!");//注意這裏沒有\n
          _exit(1);
     }
     else if (p1 > 0)
     {
          p2 = fork();
          if(p2 == 0)
          {
              printf("_Exit()1!\n");
              printf("_Exit()2!");
              _Exit(2);
          }
          else if (p2 > 0)
          {
               printf("exit()1\n");
               printf("exit()2");
               exit(3);
          }
          else
          {;}
     }
     else
     {;}
}

 2).結果截圖:
這裏寫圖片描述

 3). 結果分析:
 exit()終止進程時,清理了I/O緩衝區,而_exit()和_Exit()則沒有清理緩衝區.
 所以,exit()輸出了兩個,_exit(),_Exit()只輸出一個.

5. atexit()
 1). 終止處理程序實例:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

static void my_exit1(void);
static void my_exit2(void);
static void my_exit3(void);

int main(void)
{
     if (atexit(my_exit2) != 0)
     {
         printf("註冊my_exit2失敗!\n");
     }

     if (atexit(my_exit1) != 0)
     {
          printf("註冊my_exit1失敗!\n");
     }

     if (atexit(my_exit3) != 0)
     {
          printf("註冊my_exit3失敗!\n");
     }

     printf("main is done!\n");

     exit(0);
  //  return 0;
}

static void my_exit1(void)
{
     printf("I am my_exit1()!\n");
}

static void my_exit2(void)
{
     printf("I am my_exit2()!\n");
}

static void my_exit3(void)
{
     printf("I am my_exit3()!\n");
}

 2). 結果截圖:
這裏寫圖片描述

 3). 結果分析:
 進程終止處理函數的調用順序和註冊時候相反.

注意:內核使程序執行的唯一方法是調用一個exec函數.

  1. 參考資料:
    <<unix環境高級編程 第三版>>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章