wait()、waitpid()函数的区别(个人总结)

 子进程无论是正常或异常退出,内核都会向父进程发送信号 SIGCHILD.,因为无论是使用wait函数(阻塞),还是使用waitpid(得循环判断)都会将父进程阻塞住,而不能执行别的操作,所以,如果父进程还需要执行别的操作,就将wait/waitpid函数置于信号捕捉函数中就可以解决这个问题了,(当然也可以在父进程中单独起个线程来解决。)

wait函数、waitpid函数每次都只能回收一个子进程。

参考该文。

 wait函数是通过waitpid函数封装的:

static inline pid_t wait(int * wait_stat)

{

    return waitpid(-1,wait_stat,0);

}

1、区别1:返回值的区别

wait函数只有两个返回值,

成功返回回收的子进程id;

失败返回-1,errno被置为ECHILD。(调用进程没有子进程,调用就会失败,wait函数用这个条件来判断是否还有子进程没有回收),

waitpid函数的第三个参数设置为WNOHANG 时,返回值相较wait多了一种返回值,waitpid发现当前进程在运行,没有已退出的子进程可收集,则立即返回,返回值为0();当所有的子进程都已回收,则返回-1.(这一点与wait是一样的,同样可以根据这个参数来判断是否还有子进程没回收)

2、区别2:

wait函数会阻塞等待子进程的退出。

waitpid函数,当第三个参数使用WNOHANG时,无子进程退出,也会立刻返回(返回值为0)

3、回收多个子进程

使用waitpid来循环回收子进程(不需要知道子进程的数量)

方法一:使用信号,在捕捉函数中调用waitpid

此处使用了信号的形式来:

else if (pid > 0) {
            Close(connfd);
 
signal(SIGCHLD,wait_child);
        }  
 
main函数外定义回调函数
 
void wait_child(int signo)
{
     while(watipid(0,NULL,WNOHANG)>0);  //大于0则继续回收
          return;
}

 方法二:直接在父进程中调用waitpid,参考该文。

while(1) /*无限循环保证所有子进程全部回收*/
        {
            pid_t wpid = waitpid(-1/*回收任何子进程*/, NULL, WNOHANG);
            if(wpid == -1)
            {
                break; /*如果返回-1说明已经没有子进程了,退出循环*/
            }
            if(wpid > 0)
            {
                printf("wpid: %d\n", wpid); /*打印被回收的子进程的ID*/
            }
        }

//while循环中,没有使用sleep函数,也就是说,没有进程可回收,就立马返回。

//这个函数,其实还可以再加一句,
if(wpid==0)
   continue;

使用wait函数来循环回收子进程(wait函数是阻塞进程的),参考该文

使用wait()回收多个子进程
首先使用wait()函数来回收多个子进程,我们可以在一个for循环中等待子进程的结束,创建了几个子进程就for循环等待几次,代码如下

/************************************************************
  >File Name  : mutipwait.c
  >Author     : Mindtechnist
  >Company    : Mindtechnist
  >Create Time: 2022年05月20日 星期五 17时23分57秒
************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
 
int main(int argc, char* argv[])
{
    int i = 0;
    pid_t pid;
    for(i = 0; i < 5; i++)
    {
        pid = fork();
        if(pid == 0)
        {
            printf("child: %d\n", getpid());
            break;
        }
    }
    sleep(i);
    if(i == 5) /*只有父进程可以执行到i=5*/
    {
        for(i = 0; i < 5; i++)
        {
            pid_t wpid = wait(NULL);
            printf("wpid: %d\n", wpid);
        }
        while(1)
        {
            sleep(1);
        }
    }
    return 0;
}
//使用wait函数循环回收子进程是否也可以向waitpid一样,可以不知道进程个数呢?
这个待测试

while(wait(NULL)>0);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值