分类:
2008-10-13 16:30:49
除虫记之六(组件调用:7小时/1人)
现在来描述另一个bug,下面的话也是过了3天后回想写的。
现象是:安装后,程序运行cpu一直保持在50%以上,这个现象也只在一台开发的机器上出现。
在那台开发的机器上用taskinfo工具查看,发现磁盘的io读写非常多,都是在写一个文件,开发人员说是在发生异常的情况下才写这个日志的,查看里面的内容,发现是连接登陆模块的客户竟然达到239个,而我们的程序中连接登陆模块的就两个,一个是客户端,一个是聊天。
为什么会这么多?没有道理啊。
不管怎么说,告诉开发人员,写这个日志不要在循环里面写,在循环外面写,写一次就可以了,先降低磁盘io读写再说。
修改了相关代码后,发现cpu是降下来了,但又发现了一个问题,在那台机器上登陆模块不能自动的退出!我的开发人员真是一个非常好的小伙子,发现这个问题后,又开始了这个bug的追踪,这一追,就追到了凌晨3点,和我们追之五中的bug一起回的家。
按照设计要求,在没有客户连接的情况下,登陆模块要能自动退出的。现在的情况是如果手动杀死客户端和聊天这两个进程,在那台机器上就是不能退出登陆模块。
通过写日志查看连接数,没有发现什么问题。
怀疑是不是定时器没有杀死造成定时器的线程还在访问组件,但通过跟踪判断好像也不是这个原因。
中间过程很多次,用了很多种方法,都没有查出原因。
但最后讨论总结,登陆模块没有退出是因为已经把他注册到了ROT中,系统维护了一个连接计数的,没有退回,应该是系统的连接计数不是0造成的,虽然自己代码中的连接计数是0了。
多次运行,发现客户端进程竟然可以启动多个实例,这也不对啊,客户端进程要求单实例的啊。为什么能启动多个实例呢?
。。。。。。。。。。
最后发现原因是这样的,因为要运行单实例,那么再第二个进程退出的时候会执行到ExitInstance中,在这个里面调用了组件对象的一些功能,因为这时发现并没有创建组件,所以在这个函数里面又创建了一个组件连接,然后退出,哈哈,系统的连接计数当然不是0啦。
这个原因应该是和除虫记之五里面的一样,那个bug解决后,流程正确了,那么这个bug也没有了。在这个ExitInstance中也就不会出现再次连接的现象了。
教训:ROT中的对象不能退出,肯定是连接计数不为0。