Linux学习_系统进程的wait()函数

wait()函数

作用:避免子进程变成僵尸进程。父进程每隔一段时间来查询子进程是否结束并回收,调用wait()或者waitpid(),通知内核释放僵尸进程。
函数原型:

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

pid_t wait(int *status);
返回:成功返回子进程ID,出错返回-1
功能:等待子进程退出并回收,防止孤儿进程产生。

pid_t waitpid(pid_t pid, int *status, int options);
返回:成功返回子进程ID,出错返回-1
功能:wait函数的非阻塞版本。
  • wait和waitpid函数区别

    • 在一个子进程终止前,wait使其调用者阻塞(等待)
    • waitpid有一个选择项,可使调用者不阻塞
    • waitpid等待一个指定的子进程,而wait等待所有的子进程,返回任一终止子进程的状态。
  • status参数

    • 为空时,代表任意状态结束的子进程; 若不为空,则代表指定状态结束的子进程。
    • 获得当前所结束的子进程的状态
  • 检查wait和waitpid函数返回终止状态的宏

    • 以下三组宏
    • WIFEXITED(status) / WEXITSTATUS(status)
      • w if exited 判断是否正常终止
      • 若为正常终止子进程返回的状态,则为真
    • WIFSIGNALED(status) / WTERMSIG(status)
      • 若为异常终止子进程返回的状态,则为真(接到一个不能捕捉的信号)
    • WIFSTOPED(status) / WSTOPSIG(status)
      • 判断子程序是否暂停过 w if stoped
      • 若为当前暂停子进程返回的状态,则为真
  • options参数

    • WNOHANG
      • 若由pid指定的子进程没有退出则立即返回,则waitpid不阻塞,此时返回值为0。
    • WUNTRACED
      • 若某实现支持作业控制,则由pid指定的任一子进程状态已暂停,且其状态自暂停以来还未报告过,则返回其状态。

示例:

/*
 * process_wait.c
 *wait
 */


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

void out_status(int status)
{
	//printf("status: %d\n",status); //直接输出状态码时,输出了768,768是和3有关系计算处理后的数字
	if(WIFEXITED(status))
	printf("normal exit: %d\n", WEXITSTATUS(status));
	else if(WIFSIGNALED(status))
	printf("abnormal term: %d\n", WTERMSIG(status));
	else if(WIFSTOPPED(status))
	printf("stopped sig: %d\n", WSTOPSIG(status));
	else printf("unknown sig\n");
	}


int main(int argc, char **argv)
{
	int status;
	pid_t pid;
	if((pid=fork())<0)
	{perror("");exit(1);}
	else if(pid==0)
	{
		printf("pid: %d, ppid: %d\n",getpid(),getppid());
		exit(3); //子进程终止运行(异常终止)
	}
	//父进程调用wait函数阻塞,等待子进程结束并回收
	wait(&status);
	printf("\n");
	out_status(status);
	printf("----------------------\n");
	
	if((pid=fork())<0)
	{perror("");exit(1);}
	else if(pid==0)
	{
		printf("pid: %d, ppid: %d\n",getpid(),getppid());
		int i=3,j=0;
		int k=i / j;    // 除0会出现异常终止,返回信号编码8
		printf("k: %d\n",k);
	}
	wait(&status);
	printf("\n");
	out_status(status);
	printf("----------------------\n");
	
	
	if((pid=fork())<0)
	{perror("");exit(1);}
	else if(pid==0)
	{
		printf("pid: %d, ppid: %d\n",getpid(),getppid());
		pause();
	}
	/*
	do{
		pid = waitpid(pid,&status, WNOHANG | WUNTRACED);
		if(pid==0)sleep(1);
	}while(pid==0);
	*/
	wait(&status);
	printf("\n");
	out_status(status);
	printf("----------------------\n");
	
	
	return 0;
}


输出

$ ./process_wait 

pid: 9329, ppid: 9328
normal exit: 3
----------------------
pid: 9330, ppid: 9328
abnormal term: 8
----------------------
pid: 9331, ppid: 9328
 //pause()必须给它发送信号反应
abnormal term: 9
----------------------

另一个终端
$ kill -9 9331 发送信号编号9给到9931进程

$ kill -19 9331 
当使用wait函数时,此处无法发送19给到9931进程
发送stop只能使用waitpid时使用

$ ./process_waitpid 
pid: 9708, ppid: 9707

normal exit: 3
----------------------
pid: 9709, ppid: 9707

abnormal term: 8
----------------------
pid: 9710, ppid: 9707

stopped sig: 19
----------------------

$ kill -19 9710


$ kill -l 查看当前能够暂停的信号编号
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX	

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值