1. 程式人生 > >4.Linux核心設計與實現 P31---淺析程序終結關鍵do_exit(轉)

4.Linux核心設計與實現 P31---淺析程序終結關鍵do_exit(轉)

程序在退出時,必須釋放它所擁有的資源,並通過某種方式告訴父程序。程序的退出一般是顯示或隱式地呼叫了eixt(),或者接受了某種訊號。不過什麼原因退出,最終都呼叫了do_exit。


用於程序退出的系統呼叫有兩個exit和exit_group,exit只是終止某個程序,而exit_group整個執行緒中的程序。它們在核心中的服務函式分別為sys_exit和sys_exit_group,它們又分別呼叫了do_exit和do_group_exit。而do_group最終又呼叫了do_exit。

do_exit定義在kernel/exit.c中:

僵死程序:僵死程序是一個程序已經退出,它的記憶體和資源已經釋放掉了,但是位了時系統在它退出後能夠獲得它的退出狀態等資訊,它的程序描述符仍然保留。

一個程序退出時,它的父程序會接收到一個SIGCHLD訊號,一般情況下這個訊號的處理函式會執行wait系列函式等待子程序的結束。從子程序退出到父程序呼叫wait(子程序結束)的這段時間,子程序稱為僵死程序。執行ps –ef命令以“z”結尾的為僵死程序。

僵死程序很特殊,它沒有任何可執行程式碼,不會被排程,只有一個程序描述符用來記錄退出等狀態,除此之外不再佔用其他任何資源。

如果僵死程序的父程序沒有呼叫wait,則該程序會一直處於僵死狀態。如果父程序結束,核心會在當前執行緒組裡為其找一個父程序,如果沒找到則把init作為其父程序,此時新的父程序將負責清楚其程序。如果父程序一直不結束,該程序會一直僵死。在root下用kill -9 也不能將其殺死。

下面只對do_exit重點地方解析下: 


  1. struct task_struct *tsk = current;//獲取當前要釋放程序的程序描述符 


    exit_signals(tsk);  /* sets PF_EXITING 以免內和其他部分訪問該程序*/ 

    exit_mm(tsk);  
  2.     if (group_dead)  
  3.         acct_process();  
  4.     trace_sched_process_exit(tsk);  
  5.     exit_sem(tsk);  
  6.     exit_files(tsk);  
  7.     exit_fs(tsk);  
  8.     check_stack_usage();  

  9. /*更新父子關係,並告訴父程序正在退出*/
  10.     exit_notify(tsk, group_dead);
  11. /*切換到其他程序*/
  12.     schedule(); 
  13.     exit_thread();