父進程回收子進程之wait()函數使用解讀

1、wait的工作原理

(1)子進程結束時,系統向其父進程發送SIGCHILD信號

(2)父進程調用wait函數後阻塞

(3)父進程被SIGCHILD信號喚醒,然後去回收殭屍子進程

(4)父子進程之間是異步的,SIGCHILD信號機制就是爲了解決父子進程之間的異步通信問題,讓父進程可以及時的去回收殭屍子進程

(5)若父進程沒有任何子進程則wait返回錯誤。

 

2、參數解讀

(1)wait的參數status。

  • status用來返回子進程結束時的狀態,父進程通過wait得到status後就可以知道子進程的一些結束狀態信息。

(2)wait的返回值pid_t。

  • 這個返回值就是本次wait回收的子進程的PID。當前進程有可能有多個子進程,wait函數阻塞直到其中一個子進程結束wait就會返回,wait的返回值就可以用來判斷到底是哪一個子進程本次被回收了。

(3)小結:wait主要是用來回收子進程資源,回收同時還可以得知被回收子進程的pid和退出狀態。

(4)WIFEXITED、 WIFSIGNALED、 WEXITSTATUS這幾個宏用來獲取子進程的退出狀態。

  • WIFEXITED宏用來判斷子進程是否正常終止(return、exit、_exit退出)。
  • WIFSIGNALED宏用來判斷子進程是否非正常終止(被信號所終止)。
  • WEXITSTATUS宏用來得到正常終止情況下的進程返回值。

 

3、fork後wait回收編程實例

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(void)
{
	pid_t p1 = -1;
	pid_t ret = -1;
	int status = 0;
	
	p1 = fork();	//返回2次
	
	if(p1 == 0)
	{
		//這裏一定是子進程
		printf("子進程,pid = %d.\n", getpid());
	}
    else if(p1 > 0)
	{
		//這裏一定是父進程
		printf("parent.\n");
		ret = wait(&status);
		
		printf("子進程已經被回收,子進程pid = %d.\n", ret);
		printf("子進程是否被正常回收: %d.\n", WIFEXITED(status));
	}

	else 
	{
		//這裏一定是fork出錯了
		perror("fork");
		return -1;
	} 
	
	return 0;
}

 

4、wait和waitpd差別

(1)基本功能一樣,都是用來回收子進程的

(2)waitpid可以回收指定PID的子進程

(3)waitpid可以阻塞或者非阻塞兩種工作模式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章