1. 程式人生 > >Linux程序控制--程序退出和等待

Linux程序控制--程序退出和等待

Linux程序退出

1. 程序退出的場景
  • 程式碼執行完畢正常退出,結果正確
  • 程式碼執行完畢正常退出,結果不正確
  • 異常退出
2 .程序常見退出方式
  • 正常退出 從main() 函式中返回return退出 呼叫exit()函式退出 呼叫_exit()函式退出
  • 異常退出 由訊號終止

return return是常見的程序退出方式,執行return等同於執行exit函式,main()函式中return n函式返回值作為exit(n)函式的引數 exit() exit()是c庫函式其執行流程 首先呼叫使用者定義的清理函式ateixt或者on_exit,清理標準輸出快取去(將輸出快取區內容寫入檔案),關閉所有開啟的檔案流等,然後回撥用_eixt()函式。 需要注意的是由fork()函式建立的子程序分支裡,正常情況下使用函式exit()是不正確的,這是因為使用它會導致標準輸入輸出的緩衝區被清空兩次,而且臨時檔案可能被意外刪除 另外需要注意的是呼叫exit() 函式會結束掉整個程序組中的所有程序(執行緒) _exit()

正常退出的方式最終都會呼叫_exit()函式。 _exit()函式原形 void _eixt(int status); 包含在unistd.h庫中 其中引數status定義了程序的終止狀態, 父程序可以通過wait() 獲取。 status(後16位): 在這裡插入圖片描述

Linux程序等待

建立子程序後如果父程序不等待,子程序退出後會成為殭屍程序,直到父程序來獲取退出資訊後才會釋放剩餘資源,並且此時該程序無法被訊號殺死,繼續佔用資源造成記憶體洩露。 程序等待方式: wait() 函式原形:pid_t wait(int * status); 返回值:退出的子程序的pid,失敗返回-1 引數:輸出型引數,用於獲取子程序退出狀態碼,不關心可以置為NULL 是一個阻塞式等待,必須等到有一個子程序退出後獲取退出狀態,釋放資源才可以返回 waitpid()

函式原形:pid_t waitpid(pid_t pid, int * status, int options); 返回值:當正常退出時返回退出程序的pid, 當呼叫失敗(沒有子程序)返回-1 errno會被設定成相應的值表示錯誤原因,可以通過perror函式進行列印錯誤,當options被設定為WNOHANG時如果此時沒有已退出的子程序或者需要等待的子程序沒有退出,則返回0 引數: pid: pid 可以設定成-1表示等待任一程序,也可以設定成子程序的pid 指定需要等待的子程序。設定成0表示等待和程序組id相同的程序,當設定為<0時等待pid和其絕對值的相同的子程序; status: 和wait引數status相同,獲取退出狀態碼,如果不關心可以置為NULL options:選項引數,設定成0同wait()進行阻塞等待,設定為WNOHANG時不阻塞如果沒有退出的程序或者需要等待的子程序將直接返回0,另外這個引數還可以設定成其它屬性。 另外兩個函式可以解讀狀態碼status WTERMSIG(status)檢視程序是否正常退出,若子程序正常退出則為真 WIFSIGNALED(status)檢視程序退出狀態碼 也可以自己通過位運算來獲取退出狀態

  1 #include <unistd.h>
  2 #include <stdlib.h>
  3 #include <errno.h>
  4 #include <string.h>
  5 #include <stdio.h>
  6 
  7 int main()
  8 {
  9     pid_t pid = fork();
 10     if(pid < 0)
 11     {
 12         perror("creat child error");
 13     }
 14     else if(pid == 0)
 15     {
 16         printf("this is child:%d\n", getpid());
 17         sleep(10);
 18         _exit(10);
 19     }else if(pid > 0)
 20     {
 21         printf("this is parent:%d\n", getpid());
 22         int sta = 0;
 23         int ret = wait(&sta);
 24         if(ret > 0 && (sta & 0xFF) == 0)//後8位為0時正常退出
 25         {
 26             printf("child exit code:%d\n", (sta >> 8)&0xFF);
 27         }else if(ret > 0)//異常退出
 28         {
 29             printf("sig code:%d\n", sta & 0x7F);
 30         }
 31     }
 32     return 0;
 33 }

在這裡插入圖片描述 在這裡插入圖片描述 在這裡插入圖片描述