主进程等待子进程结束

      子进程先于父进程退出时,如果父进程没有调用wait和waitpid函数,子进程就会进入僵死状态。如果父进程调用了wait或waitpid函数,就不会使子进程变为僵尸进程。这两个函数的声明如下:

#include 
#include 

pid_t wait(int *statloc);
pid_t waitpid(pid_t pid, int *statloc, int options);


      (1)wait函数使父进程暂停执行,直到它的一个子进程结束为止。该函数的返回值是终止运行的子进程的PID。参数statloc所指向的变量存放子进程的退出码,即从子进程的main函数返回的值或子进程中exit函数的参数。如果statloc不是一个空指针,状态信息将被写入它指向的变量。

      (2)waitpid也用来等待子进程的结束,但它用于等待某个特定进程结束。参数pid指明要等待的子进程的PID。参数statloc的含义与wait函数中的statloc相同。options参数允许用户改变waitpid的行为,若将该参数赋值为WNOHANG,则使父进程不被挂起而立即返回并执行其后的代码。


      注意:(1)wait等待第一个终止的子进程,而waitpid则可以指定等待特定的子进程。

                (2)waitpid提供了一个wait的非阻塞版本。有时希望取得一个子进程的状态,但不想使父进程阻塞,waitpid提供了一个这样的选项:WNOHANG,它可以使调用者不阻塞。


#include 
#include 
#include 
#include 

int main()
{
	pid_t	pid;
	char  	*msg;
	int   	k;
	int   	exit_code;

	printf("Study how to get exit code\n");
	pid = fork();
	switch(pid) {
		case 0:
			//子进程
			msg = "Child process is running";
			k = 5;
			exit_code = 37;
			break;
		case -1:
			perror("Process creation failed\n");
			exit(1);
		default:
			//父进程
			exit_code = 0;
			break;
	}

	// 父进程等待子进程结束
	if(pid != 0) {  
		int 	stat_val;
		pid_t 	child_pid;
		
		child_pid = wait(&stat_val);
		
		printf("Child process has exited, pid = %d\n",child_pid);
		if(WIFEXITED(stat_val))
         		printf("Child exited with code %d\n",WEXITSTATUS(stat_val));
       		else
        		printf("Child exited abnormally\n");
	}
	// 子进程暂停5秒,在这个过程中可以运行命令ps aux查看父进程状态
	else {
		while(k-->0) {
			puts(msg);
			sleep(1);
		}
	}

	// 父子进程都会执行以下这段代码。父进程的exit_code是0,而子进程的exit_code是37
	exit(exit_code);
}


      程序运行结果如下:

主进程等待子进程结束_第1张图片

      父进程调用wait后被挂起等待(此时打开另外一个终端,输入命令ps aux可以看到父进程的状态为S),直到子进程结束为止。子进程正常结束后,wait函数返回刚刚结束运行的子进程的pid,宏WEXITSTATUS获取子进程的退出码(本例中设置为37)。


主进程等待子进程结束_第2张图片

你可能感兴趣的:(C)