fork函数_Linux中子进程回收函数:wait和waitpid

本文详细介绍了Linux环境下,父进程如何使用wait和waitpid函数回收子进程资源。wait函数用于等待任意子进程结束,而waitpid可以指定等待特定子进程,并提供了更多的选项。文章通过代码示例展示了这两个函数的使用方法,并提出了关于exit函数与wait不同之处的问题供读者思考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

b174deb90d4c24db94bd8a61b2ce2702.png

图控大叔

构图传递思想

阅读从未如此简单!!!

01

前言

       在进程的开发中,我们常常需要创建子进程来实现进程的“分身”,但是子进程执行完任务之后,需要父进程对其进行资源回收,否则该子进程将变成僵尸进程。那么父进程对子进程的资源回收所用到的函数则有我们今天的主角:wait和waitpid。

02

函数讲解

db27a4a4b24ef6f980111330f485e15b.gifwait()函数说明
wait函数

需要包含头文件
#include 
#include 

函数原型
pid_t wait (int * status);

参数说明:
1、如果父进程需要知道子进程结束时候的状态值.则可以填充参数
  如:
    int status;
    //创建子进程及相应判断
    printf("wait(&status) is %d\n",wait(&status));
2、如果父进程不需要知道子进程结束时候的状态值.则可以填充NULL
  如:
    int status;
    //创建子进程及相应判断
    printf("wait(NULL) is %d\n",wait(NULL));

返回值
  1、 -1 ---》该子进程不存在
  2、 子进程pid
  
其他说明
1、wait函数的调用暂时停止目前进程的执行, 直到有信号来到或子进程结束
2、如果同时创建了多个子进程,并且这些子进程都有调用退出函数,如:exit
   哪个子进程先介绍,wait就先返回哪个子进程的pid值
  (小编做了好多次测试,发现都是其他一样效果,后来在老师的指导下才纠正了这个思维定式的问题)
db27a4a4b24ef6f980111330f485e15b.gifwaitpid()函数说明
waitpid函数

需包含头文件
#include 
#include 

函数原型
pid_t waitpid(pid_t pid, int * status, int options);

参数说明:
pid:
   pid<-1 等待进程组识别码为 pid 绝对值的任何子进程.
   pid=-1 等待任何子进程, 相当于 wait().
   pid=0  等待进程组识别码与目前进程相同的任何子进程. (和wait()一样)
   pid>0  等待任何子进程识别码为 pid 的子进程.
   说明:pid 乱填,该进程组内没有此pid的子进程,会返回-1
   
status:
  用法和wait一样
  
options:
一般填0,有以下其他种选择,小编还没有弄懂,以后弄懂了再补充

其他选择为:
WNOHANG
  如果没有任何已经结束的子进程则马上返回, 不予以等待.
WUNTRACED
  如果子进程进入暂停执行情况则马上返回, 但结束状态不予以理会.
  子进程的结束状态返回后存于 status, 底下有几个宏可判别结束情况
WIFEXITED(status)
  如果子进程正常结束则为非 0 值.
WEXITSTATUS(status)
  取得子进程 exit()返回的结束代码,
  一般会先用 WIFEXITED 来判断是否正常结束才能使用此宏.
WIFSIGNALED(status)
  如果子进程是因为信号而结束则此宏值为真
WTERMSIG(status)
  取得子进程因信号而中止的信号代码, 一般会先用 WIFSIGNALED 来判断后才使用此宏.
WIFSTOPPED(status)
  如果子进程处于暂停执行情况则此宏值为真. 一般只有使用 WUNTRACED 时才会有此情况.
WSTOPSIG(status)
  取得引发子进程暂停的信号代码, 一般会先用 WIFSTOPPED 来判断后才使用此宏.

返回值:
  和wait一样。
  
其他说明:

waitpid
  1、如果所填pid所对应子进程不存在,则立即返回-1
  2、如果所填pid存在,但是一直不退出,则一直等待
    该子进程不退出为可能
      1、调用了pause()
      2、vfork函数创建的子进程未调用exit
        因为fork函数创建的子进程调用return或者exit都可以退出
      3、一直处于while循环中
      4、还有其他情况,小编可能不知道
d81a9fc314a0bfd02ddf53628460ca95.png01

图片补充

03

代码

db27a4a4b24ef6f980111330f485e15b.gif参考测试代码
#include 
#include 

int main(int argc,const char **argv){
  pid_t cpid[2];
  int status;
  
  cpid[0] = fork();

  if(cpid[0] == -1)
  {
    perror("进程1创建失败\n");
    return -1;
  }
  else if(cpid[0]==0)
  {

      printf("client1 id %d father id %d\n",getpid(),getppid());
      //sleep(0);
      //pause();
        exit(0);
  }
  
  cpid[1] = fork();
  //printf("开始 2\n");
  if(cpid[1] == -1)
  {
    perror("进程2创建失败\n");
    return -1;
  }
    if(cpid[1]==0)
  {

        printf("client2 id %d father id %d\n",getpid(),getppid());
        //sleep(2);
        //pause();
        //return 0;
             exit(0);
  }
  else{
      //wait(&status);
    
      //printf("wait is %d\n",wait(&status));//首先结束第一个创建的子程序
      //printf("wait is %d\n",wait(&status));
      //printf("wait(&status) is %d\n",wait(&status));
      printf("wait is %d\n",waitpid(cpid[1],&status,WIFEXITED(status)));
      //printf("wait cpid[1] %d is %d\n",cpid[1],waitpid(cpid[1],&status,0));
  
      printf("father id is %d\n",getpid());
    
  }
  return 0;
}

04

留个问题

       exit函数让调用者所对应进程结束,那么exit函数有负责进程资源的回收吗?答案是没有。exit和wait有什么不一样?当然有,自己总结!

05

结尾

       本次关于Linux环境下子进程内存资源的回收所涉及的部分函数:wait和waitpid就分享到这里,如有纰漏,希望不吝赐教!谢谢阅读!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值