Linux 程序等待

2021-10-01 03:16:29 字數 3587 閱讀 1341

目錄

程序等待

程序等待的必要性

程序等待的方法

wait()

waitpid()

引數int* status

誰要等待? 等待什麼? 為什麼要等待 ?

首先要知道程序終止或退出的時候會發生什麼,  程序退出時會關閉所有檔案描述符, 釋放在使用者空間分配的記憶體, 但是pcb卻會暫時保留, 裡面存著退出狀態, 比如乙個程序正常退出, pcb裡面就放著程序的退出狀態(也就是退出碼). 如果是異常退出( 前面說到, 肯定是收到訊號了), 那麼pcb裡面存放著導致該程序終止的訊號.

子程序的退出狀態講道理是該由父程序**的( 自己生的孩子, 自己就得負責 ), 也就是說,父程序必須得等待子程序退出,接收子程序的退出狀態. 如果子程序的退出狀態父程序一直沒有獲取, 那麼此時子程序就處於僵死狀態, 成為殭屍程序 . 

回答開頭的問題: 父程序要等待;  等待子程序退出;  為了拿到子程序的退出狀態, 防止子程序一直處於殭屍狀態

簡單來說, 就是父程序需要知道, 派給子程序的任務完成的如何, 結果對還是不對,或者是否正常退出. 父程序通過程序等待的方式,**子程序資源,獲取子程序退出資訊. 

說了一大堆,如何等待

標頭檔案 :sys/wait.hpid_t  wait (int* status)返回值:  成功返回被等待程序pid,  失敗則返回 -1. (成功指的是被子程序正常退出, 失敗指的是被子程式異常終止)

引數:  int* status, 是輸出型引數,獲取子程序退出狀態, 將其退出狀態存到status所指向的記憶體空間, 不關心被子程序退出狀態則可以設定status為null

wait() 是阻塞的, 在wait 返回之前, 阻塞等待子程序退出, 再返回 .

阻塞與非阻塞

pid_ t  waitpid (pid_t pid, int *status, int options引數:pid :int* status:

後面詳細看status和wifexited, wexitstatus這兩個巨集

options: options = 1時, waitpid是非阻塞的, options = 其他值時 waitpid() 是阻塞的

返回值

有三種返回值

=-1 :waitpid()出錯

= 0 :沒有等到子程序退出

>0 :等到子程序退出, 返回子程序pid

詳細來看:

ps:  當waitpid是waitpid(-1, &status, 非1) 等效 wait (&status)

不關心子程序退出碼時 waitpid(-1, null, 非1) 等效 wait (null)

前面說到. wait/waitpid都可以獲取到退出的子程序的退出狀態, 那麼獲取到的狀態在哪兒儲存呢 ?

這就需要我們事先申請一塊記憶體空間來儲存, 即 int status; 用這個int型變數來儲存退出狀態, 那麼wait/waitpid又如何知道, 要將退

出狀態給我們事先申請好的這個變數呢? 傳入這個變數的指標, 由作業系統填充.

前面說到, 程序在退出時, 會有正常退出和異常退出(終止), 那麼乙個int 型變數如何儲存這兩種不同些情況的的退出狀態呢 ?

如下圖:

可以看到, 在正常退出時, status這個int型變數, 只有低16位用到了

即, 在正常退出時, 低16位中的高8位存的是子程序得退出碼, 後8位全為0,

在異常退出時, 底7位存的是程序的異常退出訊號值, 第8位是core dump 標誌, 即核心轉儲檔案標誌, 為了使用者方便檢視異常終止

的資訊, 此時低16位中的高8位未用

所以, 在wait/waitpid結束後,  要先取出dtatus的低7位看子程序是不是異常終止, 如果不是, 再來看退出碼, 如下:

if (!(status & 0x7f)) 

else

這樣寫很麻煩, 而且還容易出錯, 所以系統就將 !(status & 0x7f) 和 (status >> 8) & 0xff 封裝成了兩個巨集

即wifexited 和 wexitstatus , 既上面的**可以寫成如下:

if (wifexited(status)) 

else

舉栗子wait.c 

用wait() 模擬父母接孩子的場景, 父母就像wait() 阻塞一樣, 不管多久, 都會等著我們, 直到接到我們.

#include#include#include#includeint main()

else if(pid == 0)

int status = -1;

wait(&status);

if (!(status & 0x7f))

else

return 0;

}

在30秒後, 列印出了30分鐘後接上了孩子 

如果我們在另乙個視窗下用kill -9 殺死子程序, 此時子程序就是異常終止了, 執行如下:

用waitpid模擬計程車司機在車站等待拉乘客的場景, 計程車司機會一直去詢問旅客乘不乘車, 當長的時間拉不到人, 就離開去別的地方拉乘客了

LINUX 程序等待

wait 函式一般用在父程序中等待 子程序的資源,而防止殭屍程序的產生。什麼是殭屍程序?pid t wait int status 引數 status 是乙個整形指標。如果status不是乙個空指標,則終止程序的終止狀態將儲存在該指標所指向的記憶體單元中。如果不關心終止狀態,可以將 status引數...

Linux 程序等待

阻塞等待 為了完成乙個功能發起呼叫,當前若不具備完成條件,等待直到條件具備完成功能後返回 非阻塞等待 為了完成乙個功能發起呼叫,當前若不具備完成條件,則立即報錯返回 wait方法 功能 阻塞等待 任意乙個子程序退出,獲取返回值 include include pid t wait int statu...

Linux 程序等待

include include pid t wait int status 返回值 成功返回等待程序pid,失敗返回 1.引數 輸出型引數,獲取最近稱退出狀態,不關心則可以設定為nullpid t waitpid pid t pid,int status,int optons 返回值 當正常返回的時...