那么当子进程结束的时候,父进程怎样才能调用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循环的
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
SignalHandle 中已经用了
#6
为什么一定要有pause函数?直接等待信号的到来不行么?
#7
直接在信号处理函数中用wait不行吗,
搞不懂为啥搞得这么复杂呢。
搞不懂为啥搞得这么复杂呢。
#8
恩,看楼上几位的回复,问题关于僵尸进程的处理问题已经解决了。呵呵,原先想的复杂了,谢谢各位啦!
#9
那具体是怎么解决的呢?
#10
那具体是怎么解决的呢?
没用信号处理, 直接在父进程中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循环的
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
考虑能否用WIFEXITED判断子进程退出状态呢?
SignalHandle 中已经用了
#6
考虑能否用WIFEXITED判断子进程退出状态呢?
SignalHandle 中已经用了
为什么一定要有pause函数?直接等待信号的到来不行么?
#7
直接在信号处理函数中用wait不行吗,
搞不懂为啥搞得这么复杂呢。
搞不懂为啥搞得这么复杂呢。
#8
恩,看楼上几位的回复,问题关于僵尸进程的处理问题已经解决了。呵呵,原先想的复杂了,谢谢各位啦!
#9
那具体是怎么解决的呢?
#10
那具体是怎么解决的呢?
没用信号处理, 直接在父进程中waitpid的