程序管理之wait和waitpid

2022-03-17 02:58:06 字數 2783 閱讀 3902

在介紹wait、waitpid和waitid函式之前,首先要介紹一下殭屍程序,因為,這三個函式的本質任務就是處理殭屍程序的問題。

程序會我們的生命體一樣,也有消亡。程序在退出時,核心會清理程序幾乎所有的資源。例如:記憶體資源、檔案資源、訊號量資源、共享記憶體資源或者引用數減一 又或釋放共享記憶體資源。但還有少量的資源沒有被核心清理,例如:程序控制塊pcb task_struct、核心棧資源。這些資源沒有被釋放,是為了保留一些程序退出是的重要資訊,例如:程序消耗的系統cpu時間、使用者cpu時間;收到了多少訊號等待這些資訊,類似於「墓誌銘」,總結了程序的一生。而wait、waitpid和waitid函式就是來釋放這些「墓誌銘」資訊的。之後程序就脫離了殭屍程序的狀態。

程序的殭屍程序的狀態,是一種「刀槍不入的狀態」,即使是用kill -9 也無法殺死。只能通過wait這些函式活著是通過init程序來「收屍」;

對於建立了很多的子程序的父程序,獲取子程序的退出資訊是非常有意義的。

include pid_t wait(int *status);
由上述返回值的含義,等待所有子程序的退出時,要注意不要丟掉對訊號中斷情況的考慮,**如下:

pit_t my_wait(int *state)

wait函式的引數和waitpid函式的引數是乙個意思。但waitpid函式對wait函式的侷限性做了擴充套件,所以,在介紹waitpid時,再來講wait的引數。

#includepid_t waitpid(pit_t pid,int *status,int options);
返回值和wait函式一樣。

pid引數

pid引數的理解:

首先給父程序要等待的子程序分類。子程序分為:和父程序同一程序組的子程序,和父程序不同程序組的子程序。子程序可以設定自己的程序組,所以某些子程序不一定和父程序歸屬於同乙個程序組;pid>0,很自然,代表要等待的子程序pid,這叫做「精準打擊」;還有情況就是分類等待子程序。由上述分類可知,與父程序為同一程序組的子程序怎麼表示,呼叫waitpid函式的父程序本來就知道自己的程序組pid,所以,不用設定引數pid的值,即給0就行;那與父程序不在同一程序組的子程序的話,就得設定引數pid的值了,但要和「精準打擊」的方式區別開,所以給負值,但取絕對值;當然,等待任意子程序的需求還是有的,而現在也正好只剩下乙個值「-1」,剛好給它用;綜述,通過上面的分析才有了pid引數的使用方式。
核心實現簡述

核心之中,wait和waitpid函式呼叫的都是wait4函式。根據pid的值來給wait_ opts結構體變數wo中的wo_type複製,再以實參的形式傳參給do_wait函式,do_wait函式來決定等待什麼狀態的子程序。

wait4中的部分**:

struct wait_opts wo;

.. //給type複製的過程

.wo.wo_type = type;

wo.wo_pid = pid;..

.ret = do_wait(&wo);

在do_ wait函式中,主要要完成兩個人物,第一,父程序中的每個執行緒都會去遍歷子程序,第二,篩選要等待的子程序;在核心中,task_struct成員中children變數是儲存子程序鍊錶的煉表頭,利用list_for_each_enpty函式來遍歷。利用eligible_pid函式來篩選。

遍歷子程序**:

static int do_wait_thread(struct wait_opts *wo,

struct task_struct *tsk)

return 0;

}

篩選子程序的**:

static int eligible_pid(struct wait_opts *wo,

struct task_struct *p)

當waitpid函式引數pid的值為-1時,wo_type的值為pidtype_max;其他三種情況由task_pid_type函式來處理。

引數options

是乙個位掩碼,可以同時存在多個標誌。當options的值為0時,行為和wait類似。

標誌位:

引數status

該引數儲存的資訊時按位儲存的,我們沒辦法解析status的值,只能通過系統提供的巨集去解析。這些巨集安功能分可以分為兩類:獲取子程序狀態和判斷是非由相應訊號產生;

wifeixited(status):正常退出,返回true;

wexitstatus(status):正常退出,獲取程序退出狀態;

wifsignaled(status): 被訊號殺死,返回true;

wtremsig(status):被訊號殺死,返回殺死程序的pid;

wcoredumop(status):子程序產生core dump,返回true;

wstopsig(status):如果子程序處於停止狀態,該巨集返回導致子進

程停止的訊號值;

wifcontinued(status): 遞送sigcont訊號,子程序回覆執行,返回true;
沒有必要返回使子程序甦醒的訊號的值,因為只有唯一乙個sigcont訊號才能使程序又停止狀態恢復到執行狀態。

程序控制之wait和waitpid函式

當乙個程序正常或異常終止時,核心就向其父程序傳送sigchld訊號。因為子程序終止是個非同步事件 這可以在父程序執行的任何時候發生 所以這種訊號也是核心向父程序發的非同步通知。父程序可以選擇忽略該訊號,或者提供乙個該訊號發生時即被呼叫執行的函式 訊號處理程式 對於這種訊號的系統預設動作是忽略它 呼叫...

程序控制之wait3和wait4函式

大多數unix系統實現提供了另外兩個函式wait3和wait4。它們提供的功能比posix.1函式wait waitpid和waitid所提供的功能要多乙個,這與附加引數rusage有關。該引數要求核心返回由終止程序及其所有子程序使用的資源彙總。include include include inc...

程序的等待(wait和waitpid)

1.程序的等待 wait函式或waitpid程序可能發生如下情況 1 如果所有的子程序孩子執行,則阻塞 block 2 如果乙個子程序已經終止,正等待父程序獲取其終止狀態,則取得孩子程序的終止狀態返回 3 如果她沒有任何子程序,則立即出錯返回 函式的原型 include pid t wait int...