wait和waitpid

wait

父进程调用wait函数回收子进程信息,防止出现僵尸进程。

  1. 阻塞等待子进程退出。
  2. 回收子进程资源(PCB)。
  3. 获取子进程结束状态。
  4. 一次wait调用回收一个子进程退出状态。
WAIT(2)                           Linux Programmer's Manual                           WAIT(2)

NAME
       wait, waitpid, waitid - wait for process to change state

SYNOPSIS
       #include <sys/types.h>
       #include <sys/wait.h>

       pid_t wait(int *status);

       pid_t waitpid(pid_t pid, int *status, int options);
DESCRIPTION
       All of these system calls are used to wait for state changes in a child of the 
       calling process, and obtain information about the child whose  state  has changed.
       A  statechange  is  considered to be: the child terminated; the child was stopped 
       by a signal; or the child was resumed by a signal.  In the case of a terminated 
       child, performing a wait  allows  the system to release the resources associated 
       with the child; if a wait is not performed, then the terminated child remains in a 
       "zombie"  state  (see  NOTES below).
       
       If a child has already changed state, then these calls return immediately.  
       Otherwise, they block until either a child changes state or a signal handler 
       interrupts the  call (assuming  that system calls are not automatically restarted 
       using the SA_RESTART flag of sigaction(2)).  In the remainder of this page, a 
       child whose state has changed  and which has not yet been waited upon by one of 
       these system calls is termed waitable.

父进程回收僵尸进程

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

int main() {
	pid_t pid, rpid;
	int i;
	
	pid = fork();
	if (pid == 0) {
		sleep(3);
		printf("I'm child pid=%d, ppid=%d\n", getpid(), getppid());
	} else if (pid > 0) {
		#if 0	
		//循环执行,因此子进程结束之后父进程没有对子进程资源进行回收
		//ps aux能看到Z+的僵尸进程
		while (1) {
			sleep(1);
			printf("I'm parent pid=%d, ppid=%d\n", getpid(), getppid());
		}
		#else
		//阻塞回收子进程
		rpid = wait(NULL);
		if (rpid == -1) {
			perror("wait error");
			exit(1);
		}
		while (1) {
			sleep(1);
			printf("I'm parent pid=%d, ppid=%d\n", getpid(), getppid());
		}
		#endif
	} 
	return 0;
}

使用status获取子进程结束状态

wait()函数的参数为一个传出参数,int类型。

  • WIFEXITED(status):如果为真,说明子进程正常结束。
    • WEXITSTATUS(status):获取子进程退出状态码。
  • WIFSIGNALED(status):如果为真,说明子进程异常结束。
    • WTERMSIG(status):获取子进程异常终止的信号编号。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

#define KILL_SIGNAL	0

int main() {
	pid_t pid, rpid;
	int i;
	int status;
	pid = fork();
	if (pid == 0) {
		printf("I'm child pid=%d, ppid=%d\n", getpid(), getppid());
		#if KILL_SIGNAL
			sleep(100);
		#else
			sleep(3);
		#endif
		exit(13);
	} else if (pid > 0) {		
		//阻塞回收子进程
		rpid = wait(&status);
		if (rpid == -1) {
			perror("wait error");
			exit(1);
		}
		if (WIFEXITED(status)) {
			printf("child exit status:%d\n", WEXITSTATUS(status));
		}
		if (WIFSIGNALED(status)) {
			printf("child killed by :%d\n", WTERMSIG(status));
		}
		while (1) {
			sleep(1);
			printf("I'm parent pid=%d, ppid=%d\n", getpid(), getppid());
		}
	} 
	return 0;
}
~# ./test
I'm child pid=53637, ppid=53636
child exit status:13
I'm parent pid=53636, ppid=23909
/*KILL_SIGNAL等于1时,在另一个终端发送kill命令*/

waitpid

pid_t waitpid(pid_t pid, int *status, int options);
可以指定回收某个pid,可以指定为非阻塞状态(WNOHANG)。后面再补充。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值