免费注册 查看新帖 |

Chinaunix

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

为什么在网络不稳定时,服务器会出现z进程? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-10-25 23:44 |只看该作者 |倒序浏览
服务器采用多进程方式,在不稳定的网络中,支持到一定的并发数后,系统会逐步出现很多zombie进程,而在稳定的网络中,就不会出现.不知为何? 这两种网络中的Linux系统都是RH,机器也都是一模一样的.

我使用到的socket类都是标准的bind,listen,accept,send,recv

请求大侠为我解惑 谢谢!



目前最新的发现是:
如果运行在linux下的服务器程序白天同时并发超过5000人(每个并发对应一个某些进程下的线程),白天会出现一些z进程,在夜间(此时并发很少)会出现更多的z进程. 当出现z进程时,系统的资源消耗很严要,运行很慢 但如果killall服务器程序后,linux系统又变得很快了

在什么时候下,系统会将某些进程杀死成z进程呢?


[ 本帖最后由 allfresh 于 2006-3-5 13:22 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2005-10-26 09:20 |只看该作者

为什么在网络不稳定时,服务器会出现z进程?

浅议Unix的defunct进程(“僵尸”进程)
本文出自:http://www2.ccw.com.cn 作者: 张道新 赵国明 (2002-04-17 08:02:00)
在Unix系统管理中,当用ps命令观察进程的执行状态时,经常看到某些进程的状态栏为defunct,这就是所谓的“僵尸”进程。“僵尸”进程是一个早已死亡的进程,但在进程表(processs table)中仍占了一个位置(slot)。由于进程表的容量是有限的,所以,defunct进程不仅占用系统的内存资源,影响系统的性能,而且如果其数目太多,还会导致系统瘫痪。

我们知道,每个Unix进程在进程表里都有一个进入点(entry),核心程序执行该进程时使用到的一切信息都存储在进入点。当用ps命令察看系统中的进程信息时,看到的就是进程表中的相关数据。当以fork()系统调用建立一个新的进程后,核心进程就会在进程表中给这个新进程分配一个进入点,然后将相关信息存储在该进入点所对应的进程表内。这些信息中有一项是其父进程的识别码。当这个进程走完了自己的生命周期后,它会执行exit()系统调用,此时原来进程表中的数据会被该进程的退出码(exit code)、执行时所用的CPU时间等数据所取代,这些数据会一直保留到系统将它传递给它的父进程为止。由此可见,defunct进程的出现时间是在子进程终止后,但是父进程尚未读取这些数据之前。利用这一点我们可以用下面的程序建立一个defunct 进程:

#include <stdio.h>;

#include<sys/types.h>;

main(){

if(!fork()){

printf(“child pid=%d\n”, getpid());

exit(0)

}

sleep(20);

printf(“parent pid=%d \n”, getpid());

exit(0);

}

当上述程序以后台的方式执行时,第8行强迫程序睡眠20秒,让用户有时间输入ps -e指令,观察进程的状态。当父进程执行终止后,再用ps -e命令观察时,我们会发现defunct进程也随之消失。这是因为父进程终止后,init 进程会接管父进程留下的这些“孤儿进程”(orphan process),而这些“孤儿进程”执行完后,它在进程表中的进入点将被删除。如果一个程序设计上有缺陷,就可能导致某个进程的父进程一直处于睡眠状态或是陷入死循环,那么当该子进程执行结束后就变成了defunct进程,这个defunct 进程可能会一直留在系统中直到系统重新启动。

如果我们将上述程序略作修改,在第8行sleep()系统调用前执行wait()或waitpid()系统调用,则子进程在终止后会立即把它在进程表中的数据返回给父进程,此时系统会立即删除该进入点。在这种情形下就不会产生defunct进程。

由于调度程序无法选中Defunct 进程,所以不能用kill命令删除Defunct 进程,惟一的方法只有重启系统

论坛徽章:
62
2016科比退役纪念章
日期:2016-06-28 17:45:06奥兰多魔术
日期:2015-05-04 22:47:40菠菜神灯
日期:2015-05-04 22:35:07菠菜神灯
日期:2015-05-04 22:35:02NBA季后赛大富翁
日期:2015-05-04 22:33:34NBA常规赛纪念章
日期:2015-05-04 22:32:032015年亚洲杯纪念徽章
日期:2015-04-14 16:54:452015年亚洲杯之朝鲜
日期:2015-03-19 23:03:16明尼苏达森林狼
日期:2015-03-16 21:51:152015小元宵徽章
日期:2015-03-06 15:57:202015年迎新春徽章
日期:2015-03-04 09:55:282015年辞旧岁徽章
日期:2015-03-03 16:54:15
3 [报告]
发表于 2005-10-26 09:53 |只看该作者

为什么在网络不稳定时,服务器会出现z进程?

不知道你的服务器是什么?apache?

如果父进程不等待子进程结束,子进程以后将成为僵尸进程,就是zombie。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。
在Linux下通过将SIGCHLD信号的操作设为SIG_IGN。
sgnal(SIGCHLD,SIG_IGN);
这样,内核在子进程结束时不会产生僵尸进程。
在上BSD下好像必须显式等待子进程结束以后才能释放僵尸进程。

但是都可以通过父进程fork两次的方法避免僵尸进程

论坛徽章:
0
4 [报告]
发表于 2005-10-26 19:30 |只看该作者

为什么在网络不稳定时,服务器会出现z进程?

原帖由 "北京野狼" 发表:
不知道你的服务器是什么?apache?

如果父进程不等待子进程结束,子进程以后将成为僵尸进程,就是zombie。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。
在Linux下通过将SIGCHLD信?.........


你好!谢谢!

服务器程序是我编写的,提供对诸多客户端的频繁数据请求.
当子进程成为z进程时,父进程是正常运行的~
比如说父进程fork出50个子进程,在不稳定的网络中50个子进程会逐步变成z进程,而在稳定的网络就不会.伺服业务代码方面的BUG不大可能,我怀疑是网络方面的底层函数用得不规范,或者是Linux系统TCP/IP协议栈方面有什么问题

论坛徽章:
0
5 [报告]
发表于 2005-10-27 08:52 |只看该作者

为什么在网络不稳定时,服务器会出现z进程?

楼主代码的问题!
为什么在网络稳定的情况下不出现,不稳定就有了呢?
看看是不是你的代码在网络不稳定的情况下根本就没去按照正常的步骤去处理运行完的子进程!只是执行了一部分代码.......

论坛徽章:
62
2016科比退役纪念章
日期:2016-06-28 17:45:06奥兰多魔术
日期:2015-05-04 22:47:40菠菜神灯
日期:2015-05-04 22:35:07菠菜神灯
日期:2015-05-04 22:35:02NBA季后赛大富翁
日期:2015-05-04 22:33:34NBA常规赛纪念章
日期:2015-05-04 22:32:032015年亚洲杯纪念徽章
日期:2015-04-14 16:54:452015年亚洲杯之朝鲜
日期:2015-03-19 23:03:16明尼苏达森林狼
日期:2015-03-16 21:51:152015小元宵徽章
日期:2015-03-06 15:57:202015年迎新春徽章
日期:2015-03-04 09:55:282015年辞旧岁徽章
日期:2015-03-03 16:54:15
6 [报告]
发表于 2005-10-27 09:27 |只看该作者

为什么在网络不稳定时,服务器会出现z进程?

我不理解为什么在网络不稳定的情况下才出现大量z进程,您说的网络不稳定是不是
访问量大的情况,其实和网络没关系?

你试试把服务程序这么写
while(1)
{
        socklen_t len;
        struct sockaddr_in client_addr;
        len = sizeof (client_addr);
        iNewSock = accept(iSock,(struct sockaddr *)&client_addr,&len);
        if (iNewSock < 0)
        {
                Error (iSock,1, "GP Can't Accept,Why?\n";
        }
        ...............
        int pid = 0;
        if((pid = fork()) == -1)
        {
                Error (iNewSock,1,"Can't fork!!!,Why?\n";
        }else if (pid == 0){
                close(iSock);
                if((pid = fork()) < 0)
                {
                        close(iSock);
                        close(iNewSock);
                        exit(1);
                }else if (pid >; 0) exit (0);
                {
                        close(iSock);
/*         进行应用操作*/
                        close(iNewSock);
                        exit (1);
                }
        }
        waitpid (pid,NULL,0);
        close(iNewSock);
}

论坛徽章:
0
7 [报告]
发表于 2005-10-27 10:09 |只看该作者

为什么在网络不稳定时,服务器会出现z进程?

首先要理解僵死进程出现的原因,建议楼主看一下这本书<<UNIX环境高级编程>;>;

论坛徽章:
0
8 [报告]
发表于 2005-10-27 23:30 |只看该作者

为什么在网络不稳定时,服务器会出现z进程?

原帖由 "me09" 发表:
楼主代码的问题!
为什么在网络稳定的情况下不出现,不稳定就有了呢?
看看是不是你的代码在网络不稳定的情况下根本就没去按照正常的步骤去处理运行完的子进程!只是执行了一部分代码.......


我也觉得是代码的问题,但真正处理业务的代码我已经检查修正容错了好几年了,实在是找不出原因,才从网络本身的问题来找.

由于这种应用不好在实际运行过程中调试,怕客户有意见,测试部门也弄不出这样的环境,所以一直不敢在实际运行过程中调试.

我下一步的方法是说服客户记录所有进程处理的每一步日志,看看 谢谢!

论坛徽章:
0
9 [报告]
发表于 2005-10-27 23:32 |只看该作者

为什么在网络不稳定时,服务器会出现z进程?

[quote]原帖由 "hongzjx"]首先要理解僵死进程出现的原因,建议楼主看一下这本书<<UNIX环境高级编程>;>;[/quote 发表:


我觉得有两种可能:
1.代码BUG
2.linux系统强制将进程回收了

我原来也试过将SIGCHLD信号ignore掉,这样由于z进程被系统进程回收了而不会出现z进程,但该有的进程真真切切是没有了啊,随时时间的推移,我的进程都慢慢死光了,然后我采用的方法是死一个补一个,最后系统资源全耗光了

论坛徽章:
0
10 [报告]
发表于 2005-10-27 23:34 |只看该作者

为什么在网络不稳定时,服务器会出现z进程?

to 北京野狼  
在出现z进程时候,访问量并不大,比如只有200并发就开始死了 而在网络环境好的网络中,达到3000以上还不会死
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP