多个子进程结束时刻未知,父进程如何回收僵死进程??

时间:2022-08-28 21:27:00
如果父进程创建了很多子进程,而且子进程的结束顺序(或时刻)是未知的,
那么当子进程结束的时候,父进程怎样才能调用wait()或waitpid()让子进程退出僵尸状态呢?

考虑使用sigprocmask+sigsuspend,先将SIGCHLD信号屏蔽,然后统计fork了多少个子进程(total个),父进程中在 解除阻塞SIGCHLD之前,调用sigsuspend,防止在解除之前有SIGCHLD信号发生,但是在解除阻塞SIGCHLD之后,如何用pause()函数再等待下一个SIGCHLD信号有时会造成一直等待的问题,因为子进程何时退出是不一定的嘛,这种情况应该怎样解决呢??


希望大家多给个思路 多个子进程结束时刻未知,父进程如何回收僵死进程??

10 个解决方案

#1


不用阻塞啊
主进程改干嘛干嘛去

sigset(SIGCHLD, Wait);  //signal
void Wait()

int pid, Status;
while(1)

pid= waitpid((pid_t)(-1), &Status, WNOHANG|WUNTRACED);
if (pid> 0) 
{
/*干些什么*/
        }
else
break;
}
}

#2


可以在信号处理程序中调用循环调用waitpid(-1,&stat,WNOHANG),
WNOHANG标志设置waitpid为非阻塞,如果没有进程结束会自己跳出while循环的

#3



int iDaypc = 0;/*记录fork的进程数*/
 void SignalHandle(int sig)
{
   signal(SIGCHLD,SignalHandle);
   int  pCount = iDaypc;
    while( (pid = waitpid(-1,&status,WNOHANG )) > 0)
                   {
                                   printf("in waitpid while\n");
                                   if ( pCount > 0 )
                                     --pCount;
                                   else if(pCount==0)
                                       break;
}


 int main()
{
 if(signal(SIGCHLD,SignalHandle)==SIG_ERR)
  {
    printf("signal(SIGCHLD) error!\n");
  } 
 
  sigemptyset(&mask);
  sigemptyset(&wait);
  sigaddset(&mask,SIGCHLD);
  if( sigprocmask(SIG_BLOCK,&mask,&oldmask) < 0)
    printf("sigprocmask error!\n");

  while(一个条件)//根据一个条件 来确定要fork多少个子进程
  {
            pid = fork();
       if(pid < 0)
        {
        perror("fork error!");
         
}
else
if(pid == 0)
                {
                 if( 0 > execl(path,stpAa.pro_name,stpAa.par,,NULL))//通过execl调起一个任务,任务什么时候跑完是不确定的!!!
                                           printf("call program: [%s] failed!\n",stpAa.pro_name);  
                 }
                 
                    if(pid > 0) 
                     /*  如果在此处wait等待回收子进程,那么岂不是父进程要阻塞等待子进程跑完了,才能继续fork下一个子进程了吗??
                  */
                    {
                        ++iDaypc;/*子进程的数加1*/
                                    
                       }
      }//end while
      printf("\nchild count is [%d],father pid=[%d]",iDaypc,getpid());
 
 printf("\nbefore sigsuspend\n"); 
   sigsuspend(&wait);
  // printf("after sigsuspend\n");
  sigprocmask(SIG_SETMASK,&oldmask,NULL); 
  return 0;
   }




但是,通过execl调起一个任务,任务什么时候跑完是不确定的啊,所以子进程何时退出也是不确定的啊

多个子进程结束时刻未知,父进程如何回收僵死进程??

#4


考虑能否用WIFEXITED判断子进程退出状态呢?

#5


引用 4 楼 alexander1977 的回复:
考虑能否用WIFEXITED判断子进程退出状态呢?

SignalHandle 中已经用了

#6


引用 5 楼 why_ny 的回复:
Quote: 引用 4 楼 alexander1977 的回复:

考虑能否用WIFEXITED判断子进程退出状态呢?

SignalHandle 中已经用了

为什么一定要有pause函数?直接等待信号的到来不行么?

#7


直接在信号处理函数中用wait不行吗,
搞不懂为啥搞得这么复杂呢。

#8


恩,看楼上几位的回复,问题关于僵尸进程的处理问题已经解决了。呵呵,原先想的复杂了,谢谢各位啦! 多个子进程结束时刻未知,父进程如何回收僵死进程??

#9


那具体是怎么解决的呢?

#10


引用 9 楼 alexander1977 的回复:
那具体是怎么解决的呢?

没用信号处理, 直接在父进程中waitpid的

#1


不用阻塞啊
主进程改干嘛干嘛去

sigset(SIGCHLD, Wait);  //signal
void Wait()

int pid, Status;
while(1)

pid= waitpid((pid_t)(-1), &Status, WNOHANG|WUNTRACED);
if (pid> 0) 
{
/*干些什么*/
        }
else
break;
}
}

#2


可以在信号处理程序中调用循环调用waitpid(-1,&stat,WNOHANG),
WNOHANG标志设置waitpid为非阻塞,如果没有进程结束会自己跳出while循环的

#3



int iDaypc = 0;/*记录fork的进程数*/
 void SignalHandle(int sig)
{
   signal(SIGCHLD,SignalHandle);
   int  pCount = iDaypc;
    while( (pid = waitpid(-1,&status,WNOHANG )) > 0)
                   {
                                   printf("in waitpid while\n");
                                   if ( pCount > 0 )
                                     --pCount;
                                   else if(pCount==0)
                                       break;
}


 int main()
{
 if(signal(SIGCHLD,SignalHandle)==SIG_ERR)
  {
    printf("signal(SIGCHLD) error!\n");
  } 
 
  sigemptyset(&mask);
  sigemptyset(&wait);
  sigaddset(&mask,SIGCHLD);
  if( sigprocmask(SIG_BLOCK,&mask,&oldmask) < 0)
    printf("sigprocmask error!\n");

  while(一个条件)//根据一个条件 来确定要fork多少个子进程
  {
            pid = fork();
       if(pid < 0)
        {
        perror("fork error!");
         
}
else
if(pid == 0)
                {
                 if( 0 > execl(path,stpAa.pro_name,stpAa.par,,NULL))//通过execl调起一个任务,任务什么时候跑完是不确定的!!!
                                           printf("call program: [%s] failed!\n",stpAa.pro_name);  
                 }
                 
                    if(pid > 0) 
                     /*  如果在此处wait等待回收子进程,那么岂不是父进程要阻塞等待子进程跑完了,才能继续fork下一个子进程了吗??
                  */
                    {
                        ++iDaypc;/*子进程的数加1*/
                                    
                       }
      }//end while
      printf("\nchild count is [%d],father pid=[%d]",iDaypc,getpid());
 
 printf("\nbefore sigsuspend\n"); 
   sigsuspend(&wait);
  // printf("after sigsuspend\n");
  sigprocmask(SIG_SETMASK,&oldmask,NULL); 
  return 0;
   }




但是,通过execl调起一个任务,任务什么时候跑完是不确定的啊,所以子进程何时退出也是不确定的啊

多个子进程结束时刻未知,父进程如何回收僵死进程??

#4


考虑能否用WIFEXITED判断子进程退出状态呢?

#5


引用 4 楼 alexander1977 的回复:
考虑能否用WIFEXITED判断子进程退出状态呢?

SignalHandle 中已经用了

#6


引用 5 楼 why_ny 的回复:
Quote: 引用 4 楼 alexander1977 的回复:

考虑能否用WIFEXITED判断子进程退出状态呢?

SignalHandle 中已经用了

为什么一定要有pause函数?直接等待信号的到来不行么?

#7


直接在信号处理函数中用wait不行吗,
搞不懂为啥搞得这么复杂呢。

#8


恩,看楼上几位的回复,问题关于僵尸进程的处理问题已经解决了。呵呵,原先想的复杂了,谢谢各位啦! 多个子进程结束时刻未知,父进程如何回收僵死进程??

#9


那具体是怎么解决的呢?

#10


引用 9 楼 alexander1977 的回复:
那具体是怎么解决的呢?

没用信号处理, 直接在父进程中waitpid的