免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 2488 | 回复: 14
打印 上一主题 下一主题

关于产生僵死进程,看看我的程序的模型是否有问题. [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-08-27 16:01 |只看该作者 |倒序浏览
void sigCatchChld(int sig)
{
        int status;
        pid_t pid;

        while ((pid = waitpid(-1, &status, WNOHANG)) >; 0) printf("child %d terminated\n", pid);
         
}

int unicomServer::Run()
{
        pid_t pid;
        socklen_t addr_size = (int)sizeof(remote_sin);

            (void)signal(SIGCHLD, sigCatchChld);
          while (1)
          {
                  conn_socket = accept(Mysocket, (struct sockaddr *)&remote_sin, &addr_size);
                  if (conn_socket < 0)
                  {
                              socket_error = MySOCKET_ACCEPT_ERROR;
                              return -1;
                    }
                    if ((pid = fork()) >; 0)
                    {
                            close(conn_socket);//父进程关闭连接描述符
           
                                         continue;
                    }
                    else if (pid == 0)
                    {
                            close(Mysocket);//子进程关闭监听描述符
                            analyzePackage(conn_socket);
                            exit(0);
                    }
                    else if (pid < 0)
                    {
                            this->;setLogInfo();
                        gTool->;writeLog("%s%s%s\n", LOG_MAINPROCESS_PROMPT, "创建子进程失败,详细信息:", logrecord_info);
                        return -2;
                    }
            }

              return 0;
}

int main()
{

  ...................
    Run();
  ..................
}
现在的问题是:
1)fork之后有僵死进程产生.
2)只有第一个子进程结束后父进程接收到了信号,进入了信号处理函数中,fork第2,3。。之后的子进程都不能进入信号处理函数之中,从而产生了僵死进程。
请问这是什么问题呢?如何解决?

论坛徽章:
0
2 [报告]
发表于 2003-08-27 20:46 |只看该作者

关于产生僵死进程,看看我的程序的模型是否有问题.

因为waitpid(-1, &status, WNOHANG)相当于wait所有的子进程结束,所以当第一次信号处理时,信号处理器在此等待,自然就block后面的信号处理。checkwaitpid函数,将-1换成子进程id,或replace waitpid with other functions.

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
3 [报告]
发表于 2003-08-27 20:49 |只看该作者

关于产生僵死进程,看看我的程序的模型是否有问题.

waipid(-1,...)只能处理接收到的第一个子进程,其他的要处理,可以在父进程中登记,然后逐个处理。

论坛徽章:
0
4 [报告]
发表于 2003-08-28 10:32 |只看该作者

关于产生僵死进程,看看我的程序的模型是否有问题.

可以fork两次,把第一次fork的进程终止,这样就可以避免僵死经常
例如:pid_t pid;
if((pid=fork())<0)
{
        err_exit("fork error";
}
else if(pid==0)
{
        if(pid=for())<0)
                err_exit("fork error";       
        else if(pid>;0)
                exit(EXIT_SUCCESS);/*终止第一次派生得进程*/
        sleep(2);
        .....
        exit(EXIT_SUCCESS);
}
if(waitpid(pid,NULL,0)!=pid)
{
        err_exit("waitpid error";       
}
exit(EXIT_SUCCESS);

论坛徽章:
0
5 [报告]
发表于 2003-08-28 12:53 |只看该作者

关于产生僵死进程,看看我的程序的模型是否有问题.

在void sigCatchChld(int sig)函数增加一行代码: (void)signal(SIGCHLD, sigCatchChld);
及该为
void sigCatchChld(int sig)
{
int status;
pid_t pid;

while ((pid = waitpid(-1, &status, WNOHANG)) >; 0) printf("child %d terminated\n", pid);
(void)signal(SIGCHLD, sigCatchChld); //增加的

}

原为信号处理函数被出发后,就没了,必须重新设置。
所以你能开到第一个子进程的结束。其他的子进程退出
没有被你的信号处理函数处理。

论坛徽章:
0
6 [报告]
发表于 2003-08-28 17:20 |只看该作者

关于产生僵死进程,看看我的程序的模型是否有问题.

"只有第一个子进程结束后父进程接收到了信号,进入了信号处理函数中,fork第2,3。。之后的子进程都不能进入信号处理函数之中,从而产生了僵死进程。"
原因是:在某些系统中,当一个进程处理完中断信号返回用户态之前,核心会清除用户区中设定的处理例程地址.在下一次进程处理该信号时使用默认值.
楼上的方法不能完美的解决此问题,因为有可能在调用signal之前,进程就得到信号,那么仍是使用默认值的.
可以参考使用signal(SIGCHLD,SIG_IGN),或者fork两次,让系统自己处理

论坛徽章:
0
7 [报告]
发表于 2003-08-28 21:58 |只看该作者

关于产生僵死进程,看看我的程序的模型是否有问题.

谢谢楼上各位的精彩回答。
我现在的疑惑不是如何避免僵死进程,处理这个signal(SIGCHLD,SIG_IGN)就可以了。
现在想作的是:
限制一下客户端的最大连接数问题!也就是要对服务器端fork进程的个数作限制,我的想法是:用一个全局变量fork之前累加已经fork的个数,然后在派生的子进程结束后使该全局变量减1,从而能够准确地记录当前服务器端派生的进程数,即客户端的连接数。因此我想根据SIGCHLD信号注册一个消息处理函数,在函数中记录全局变量的变化!
不知我的考虑是否可行,如果可行要作怎样的改动。
希望大家继续参与。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
8 [报告]
发表于 2003-08-28 22:21 |只看该作者

关于产生僵死进程,看看我的程序的模型是否有问题.

可以。

但是需要注意的是不是简单的减一就可以的。

因为信号是有可能丢失的。

论坛徽章:
0
9 [报告]
发表于 2003-08-28 23:06 |只看该作者

关于产生僵死进程,看看我的程序的模型是否有问题.

其实你不用考虑fork,只要控制连接套接字的数目就行了。

论坛徽章:
0
10 [报告]
发表于 2003-08-29 08:55 |只看该作者

关于产生僵死进程,看看我的程序的模型是否有问题.

父子进程有不同的数据空间,用全局变量的思路是错的。用进程间通信方法吧。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP