在父進程中先使用 kill
函數終止子進程,之后再使用 wait
函數是可行的,下面從原理、使用示例、注意事項幾個方面詳細說明。
原理
kill
函數:其作用是向指定進程發送信號。當向子進程發送SIGTERM
(通常用于請求進程正常終止)或者SIGKILL
(強制終止進程)這類終止信號時,子進程會收到信號并做出相應反應,一般會終止運行。子進程終止后,會進入僵尸狀態,此時它雖然已經停止執行,但仍保留一些進程信息,等待父進程調用wait
系列函數來回收這些資源。wait
函數:父進程調用wait
函數時,若有子進程處于僵尸狀態,wait
函數會獲取該子進程的終止狀態信息,然后釋放子進程占用的系統資源,將其從系統進程表中移除。
使用示例
以下代碼展示了先使用 kill
函數終止子進程,再使用 wait
函數回收子進程資源的過程:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>int main() {pid_t pid;int status;// 創建子進程pid = fork();if (pid < 0) {perror("fork");exit(EXIT_FAILURE);} else if (pid == 0) {// 子進程代碼printf("子進程開始執行,進程ID: %d\n", getpid());while (1) {// 子進程進入無限循環,模擬長時間運行的任務sleep(1);}} else {// 父進程代碼sleep(2); // 等待一段時間,確保子進程開始執行printf("父進程發送 SIGTERM 信號終止子進程 %d\n", pid);// 向子進程發送 SIGTERM 信號if (kill(pid, SIGTERM) == -1) {perror("kill");exit(EXIT_FAILURE);}// 父進程等待子進程結束pid_t terminated_pid = wait(&status);if (terminated_pid == -1) {perror("wait");exit(EXIT_FAILURE);}if (WIFSIGNALED(status)) {printf("子進程 %d 因信號 %d 終止\n", terminated_pid, WTERMSIG(status));}}return 0;
}
代碼解釋
- 子進程:創建后進入一個無限循環,模擬長時間運行的任務。
- 父進程:等待 2 秒后,使用
kill
函數向子進程發送SIGTERM
信號,請求子進程終止。然后調用wait
函數等待子進程結束,并獲取其終止狀態信息。
注意事項
- 信號處理:子進程可以捕獲并處理
SIGTERM
信號,這意味著子進程可能不會立即終止。若需要強制終止子進程,可以使用SIGKILL
信號,但要注意SIGKILL
信號不能被捕獲或忽略。 - 錯誤處理:在調用
kill
和wait
函數時,要檢查其返回值,對可能出現的錯誤進行處理。例如,kill
函數可能因為權限不足或者目標進程不存在而調用失敗。 - 僵尸進程:若不調用
wait
函數回收子進程的資源,子進程會變成僵尸進程,占用系統資源。所以在終止子進程后,務必使用wait
系列函數來回收資源。