程序相關的系統呼叫3

2021-06-14 06:19:05 字數 4210 閱讀 2067

一,程序等待:

wait函式

標頭檔案

#include

#include

函式原型

pid_t wait(int *status);

返回值 成功

失敗是否設定errno

結束的子程序的pid和結束狀態 -1

設定

引數說明:status用於接收子程序結束返回狀態值的引數。如果不關心子程序的返回狀態,status可以填null。

錯誤資訊:

echild:呼叫wait函式的程序沒有任何可以等待的子程序。

說明:wait函式返回status狀態存在兩種情況:一種是子程序正常退出,另一種是接收到了訊號而退出。當所有的子程序結束時,wait函式返回最後結束的子程序的pid和結束狀態。狀態資訊被儲存在int型別的變數中。對於32位的系統,低16為用於儲存狀態資訊,而高16位被設定為0.具體情況如下表:

status退出資訊

子程序結束情況

第四個位元組

第三個位元組

第二個位元組

第乙個位元組

正常結束 0

0退出** 0

被不能捕捉的資訊殺死 0

0 0接收到的訊號值

為了方便對wait返回的status狀態的檢查,linux系統還提供了一些巨集,如下表:

巨集定義 說明

wifexited(status)

子程序正常退出情況下返回真值(使用exit(3)或_exit(2)或在main中返回)

wexitstatus(status)

返回子程序的退出狀態,該巨集只應用於wifexited為真的情況(即子程序正常退出的情況)

wifsignaled(status)

子程序被訊號終止的情況下返回真值

wtermsig(status)

返回導致子程序結束的訊號型別,該巨集只應用於wifsignaled為真的情況(即子程序被訊號終止的情況)

wcoredump(status)

當子程序產生core  dump除錯資訊時返回真值。注意應用「在#ifdef wcoredump … #endif」的條件編譯語句中。

wifstopped(status)

當子程序接收到停止訊號時

wstopsig(status)

返回導致子程序停止的訊號型別,該巨集只應用於wifstopped為真值的情況

wifcontinued(status)

子程序接收到訊號sigcont而繼續執行(從linux2.6.10核心開始)

二,waitpid函式

標頭檔案

#include

#include

函式原型

pid_t waitpid(pid_t pid, int *status, int options);

返回值 成功

失敗是否設定errno

返回狀態及狀態改變的子程序的程序號;如果option使用wnohang引數且沒有子程序的狀態發生改變,則返回0-1

引數說明:

pid:欲等待的子程序程序號:

pid<-1:等待程序組程序號為pid絕對值的任何子程序。

pid=-1:等待任何子程序相對於wait()。

pid=0:等待程序組程序號與目前程序相同的任何子程序。

pid>0:等待程序號為pid的指定程序。

status:接收子程序結束返回狀態值的引數。如果不關心子程序的返回狀態,status可以填null。

option:提供了一些額外的選項來控制waitpid:

(1):wnohang:如果沒有子程序,則退出立即返回。

(2):wuntraced:當子程序處於停止狀態,則立即返回。

(3):wcontinued:當處於停止狀態的子程序收到sigcont訊號後接著執行返回(linux 2.6.10後的核心支援該引數)。

錯誤資訊:

echild:指定程序號的子程序不存在。

eintr:未設定wnohang引數,同時接收到了未阻塞的訊號或sigchld訊號。

einval:非法的options引數。

三,kill函式

傳送訊號給程序,讓程序終止執行是程序非正常結束的一種方法。在linux系統中,定義了64中訊號型別。使用「kill –l」

命令可以檢視這些訊號的具體資訊。使用kill命令給知道程序傳送訊號的命令格式為:kill –訊號型別程序號。例如:

kill –s sigkill。

傳送的訊號有可能被訊號捕獲,而不會起到預設的作用。例如,傳送的sigterm訊號被程序捕獲,導致程序沒有按預想結束,為了解決這一問題,linux提供了sigkill訊號,這個訊號是不會被程序捕獲的。也就是說,如果要確保殺死某個程序,可以使用:「kill –s sigkill 程序號」命令。要獲得程序的程序號資訊可以使用「ps -aux」命令。

linux系統還提供了對應的kill函式,可以在程式開發中實現與kill命令相同的功能。kill函式宣告如下:

int kill(pid_t pid, int sig);

pid為將訊號傳送到的程序號。sig為要傳送的訊號型別,可以直接使用「kill -l」命令列出的訊號型別或直接使用對應的數字。

四,殭屍程序

殭屍程序(zombie process)是由於子程序退出後父程序沒有使用wait函式收集子程序狀態而產生的。乙個程序在呼叫exit命令結束自己生命的時候,其他它並沒有真正的被銷毀,而是留下乙個稱為殭屍(zombie)的資料結構(系統呼叫exit,它的作用是使程序退出,但也僅僅限於將乙個正常的程序變成乙個殭屍程序,並不能將其完全銷毀)。在linux程序的狀態中,殭屍程序是非常特殊的一種,它已經放棄了幾乎所有記憶體空間,沒有任何可執行**,也不能被排程,僅僅在程序列表中保留乙個位置,記載該程序的退出狀態等資訊供其他程序收集,除此之外,殭屍程序不再占有任何記憶體空間。它需要它的父程序來為它收屍,如果它的父程序沒安裝sigchld訊號處理函式呼叫wait或waitpid等待子程序結束,由又沒有顯示忽略該訊號,那麼它就一直保持殭屍狀態,如果這時父程序結束了,那麼init程序自動會接手這個子程序,為它收屍,它還是能被清除的。但是如果父程序是乙個迴圈,不會結束,那麼子程序就會一直保持殭屍狀態,這就是為什麼系統中有時會有很多的殭屍程序。由於殭屍程序會占用程序表中的位置,而程序表空間是有限的,linux系統中產生程序的數量是有限的,過多的殭屍程序會影響新程序的產生。怎麼檢視殭屍程序,利用命令ps,可以看到有標誌為z的程序就是殭屍程序。

殭屍程序的存在是為了給程式設計師和系統管理員提供一些重要的程序資訊。這些資訊包括程序如何結束,在執行過程中是否出現了錯誤等。如果沒有殭屍程序,這些資訊將隨著程序的結束而消失。因此,殭屍程序攜帶的資訊對於程式開發人員和系統管理員發現程式存在問題有著非常重要的意義。

乙個簡單的產生殭屍基礎的例項:

#include #include #include #include int main(void)

else if (pid > 0)

else

return (0);

}用 ps –aux可以看到產生了乙個殭屍程序:

root 32628 0.0 0.0 1492 264 pts/2 s 20:06 0:00 ./zom

root 32629 0.0 0.0 0 0 pts/2 z 20:06 0:00 [zom]

wait例項:

#include #include #include #include #include #include int main(void)

else if (pid == 0)

else }

waitpid例項:

#include #include #include #include #include int main(void)

else if (0 == pid)

else

exit(exit_success);

}

程序管理相關的系統呼叫

2.4 程序管理相關的系統呼叫 從使用者狀態切換到核心態的方法,依不同的體系結構二各有不同。這兩種狀態之間切換的機制,並解釋使用者空間和核心空間之間如何交換引數。就目前而言,將核心視為有c標準使用的 程式庫 即可。2.4.1 程序複製 傳統的unix中用於複製程序的提供呼叫時fork.但他並不是li...

系統呼叫,程序切換

模式切換 不等同於 程序上下文切換 當程序呼叫系統呼叫或者發生中斷時,cpu從使用者模式 使用者態 切換成核心模式 核心態 此時,無論是系統呼叫程式還是中斷服務程式,都處於當前程序的上下文中,並沒有發生程序上下文切換。當系統呼叫或中斷處理程式返回時,cpu要從核心模式切換回使用者模式,此時會執行作業...

系統呼叫相關理解

系統呼叫是核心提供的使用者程序與核心進行互動的一組介面 是應用程式受限地訪問介面 提供了建立新程序並與已有程序進行通訊的機制 提供了申請作業系統其它資源的能力 是使用者訪問核心的唯一手段。主要是為了保證系統穩定可靠,避免應用程式肆意妄為。系統呼叫作為使用者空間程序和硬體裝置之間的中間層,主要作用有以...