天天看點

Linux系統程式設計之wait

#include "apue.h"
#include <sys/wait.h>
#include "apue.h"
#include <sys/wait.h>

void pr_exit(int status) //用來列印wait退出信号的函數
{
	if (WIFEXITED(status))
		printf("normal termination, exit status = %d\n",
				WEXITSTATUS(status));
	else if (WIFSIGNALED(status))
		printf("abnormal termination, signal number = %d%s\n",
				WTERMSIG(status),
#ifdef	WCOREDUMP
				WCOREDUMP(status) ? " (core file generated)" : "");
#else
				"");
#endif
	else if (WIFSTOPPED(status))
		printf("child stopped, signal number = %d\n",
				WSTOPSIG(status));
}

int
main(void)
{
	pid_t	pid;
	int		status;

	if ((pid = fork()) < 0)
		err_sys("fork error");
	else if (pid == 0)				/*子程序退出,設定退出狀态7 */
		exit(7);

	if (wait(&status) != pid)		/* 等待子程序退出 */
		err_sys("wait error");
	pr_exit(status);				/* 列印子程序退出狀态 */

	if ((pid = fork()) < 0)
		err_sys("fork error");
	else if (pid == 0)				/* child */
		abort();					/* 設定異常退出 */

	if (wait(&status) != pid)		/* wait for child */
		err_sys("wait error");
	pr_exit(status);				/* 列印異常退出狀态 */

	if ((pid = fork()) < 0)
		err_sys("fork error");
	else if (pid == 0)				/* child */
		status /= 0;				/* 除0,得到浮點數異常 */

	if (wait(&status) != pid)		/* wait for child */
		err_sys("wait error");
	pr_exit(status);				/* and print its status */

	exit(0);
}

           
normal termination, exit status = 7
abnormal termination, signal number = 6
abnormal termination, signal number = 8

           

程序一旦調用了wait,就立即阻塞自己,由wait自動分析是否目前程序的某個子程序已經退出,如果讓它找到了這樣一個已經變成僵屍的子程序,wait就會收集這個子程序的資訊,并把它徹底銷毀後傳回;如果沒有找到這樣一個子程序,wait就會一直阻塞在這裡,直到有一個出現為止。

參數status用來儲存被收集程序退出時的一些狀态,它是一個指向int類型的指針。但如果我們對這個子程序是如何死掉的毫不在意,隻想把這個僵屍程序消滅掉,(事實上絕大多數情況下,我們都會這樣想),我們就可以設定這個參數為NULL,就象下面這樣

如果成功,wait會傳回被收集的子程序的程序ID,如果調用程序沒有子程序,調用就會失敗,此時wait傳回-1,同時errno被置為ECHILD。

如果參數status的值不是NULL,wait就會把子程序退出時的狀态取出并存入其中,這是一個整數值(int),指出了子程序是正常退出還是被非正常結束的(一個程序也可以被其他程序用信号結束),以及正常結束時的傳回值,或被哪一個信号結束的等資訊。由于這些資訊被存放在一個整數的不同二進制位中,是以用正常的方法讀取會非常麻煩,人們就設計了一套專門的宏(macro)來完成這項工作,下面我們來學習一下其中最常用的兩個:

1,WIFEXITED(status) 這個宏用來指出子程序是否為正常退出的,如果是,它會傳回一個非零值。

(請注意,雖然名字一樣,這裡的參數status并不同于wait唯一的參數–指向整數的指針status,而是那個指針所指向的整數,切記不要搞混了。)

2,WEXITSTATUS(status) 當WIFEXITED傳回非零值時,我們可以用這個宏來提取子程序的傳回值,如果子程序調用exit(5)退出,WEXITSTATUS(status)就會傳回5;如果子程序調用exit(7),WEXITSTATUS(status)就會傳回7。請注意,如果程序不是正常退出的,也就是說,WIFEXITED傳回0,這個值就毫無意義。