yaoxing25
发表于 2009-7-6 23:59:42
没有使用remove_handler,只是在handle_close里删除相应的指针,
在删除的时候出现的退出比较多,
同时在运行的时候也出现过,就是什么操作也没有做运行运行就退出了。不知道这样说清楚了吗?
modern
发表于 2009-7-7 09:59:28
建议缩小范围,排查问题,
首先,可以尝试,在handle_close里不做delete this操作,
看是否仍然会有退出。
对于handle_close的里是否如何正确的使用delete this,
如果不太了解原理的话,会有很多陷阱,
C++NPV2的Sidebar 10,11有比较详细的讨论,
建议详细阅读,作为参考参考。
其次,对于退出事件循环,一般只有三种情况
1.handle_events返回错误
2.自己设置的超时到期
3.调用了end_reactor_event_loop
你的情况肯定不是2,3了,
因此可以考虑在run_reactor_event_loop内部,
处理handle_events返回值为负值的地方打个断点,
然后看一下调用堆栈,
看到底是哪步的返回值导致事件循环返回错误了。
while (1)
{
int const result = this->implementation_->handle_events ();
if (eh != 0 && (*eh)(this))
continue;
else if (result == -1 && this->implementation_->deactivated ())
return 0;
else if (result == -1)
return -1;
}
[ 本帖最后由 modern 于 2009-7-7 10:34 编辑 ]
yaoxing25
发表于 2009-7-7 22:50:49
你这段代码好像是ACE的源码吧?我也看到过 这样的代码。
我今天又调试了一下,这种情况频频出现,删除设备时,删除没有连接的设备都会出现。理论上删除没有连接的设备并没有涉及Socket呀,只是对我保存连接的MAP进行操作,可是这样也会出现run_event_loop()退出的情况。我的连接是一个线程,连接成功后会调用发送命令方法,当我发送同步命令超时的时候也会有run_event_loop()退出的情况,以前在调试过程中也没有出现这么频繁呀。
今天 好爆发了一样,可以重现但是定位不出来在哪里有问题,一时没办法呀,代码也带不出来。这是我做的一个项目,现在已经有人在使用windows socket尝试实现了,好像windows的可以实现,可是我还是想用ACE实现。有没有更好的定位手段。
winston
发表于 2009-7-7 23:08:52
windows 平台还是linux平台?
前者调试是很方便的呀。能直接定位到ACE类库内部,能查看到堆栈调用顺序表。linux也可以用GDB设置断点、查堆栈列表呀。
yaoxing25
发表于 2009-7-8 00:04:45
我使用的是windows平台,只是现在好像是一点头绪也没有,不知道如何进行调试。
而且今天的问题像爆发了。所以有点慌了呵呵。。。项目已经延期了,所以才找大家帮忙呀!
winston
发表于 2009-7-8 10:44:28
把ACE编译出的PDB文件,和运行时需要的DLL文件,放在你的程序目录,设置断点,是能够查到堆栈的。看看是什么问题,有什么样的调用关系。
yaoxing25
发表于 2009-7-8 23:54:47
我通过一个线程来发起连接,在每次连接时直接new一个client指针来发起连接。当我删除设备时是使用client->peer()->close()方法,可以直接回调handle_close()方法。在handle_timeout方法时我也会判断与设备的连接时间是否超时如果超时也是设备handle_close()方法来释放client指针。
这个过程中,如果连接成功(包括用户登录,必须的命令执行成功),我会启动一个线程来将连接成功的状态上报给业务层,这时候业务层还要发送同步命令来获取版本信息,
如果这个时候我删除该设备,就需要将这个连接句柄删除,那么是不是发生这种情况就会导致run_event_loop()退出?因为我在删除多个设备时很容易重现run_event_loop()方法退出的情况,不知道我这么认为对吗?因为删除是我通过主线程来执行的,而我的上报是另一个线程来完成的。会不会因为线程同步问题导致这个问题?
现在问题是我不知道如何来解决这个线程同步问题。太逊了吧~!~!
[ 本帖最后由 yaoxing25 于 2009-7-9 00:07 编辑 ]
modern
发表于 2009-7-9 09:13:08
几点建议:
1.winston和我都一直在说要看堆栈信息或者打断点,
方法在前面的帖子里面都已经说的很清楚了,
调试程序,猜是靠不住的。
想解决问题,请你首先务必对此给出一个答复。
2.ACE提供了可重用性相当好的Connector与Acceptor网络框架,
建议不要自己去造轮子,用法的话书上说的十分清楚。C++NPV2第七章。
3.就算想自己造轮子也可以,建议先看一下ACE自带的例子。
ACE的很多使用方法是有其背后的原因的,如果不了解原理,
那么至少模仿人家可以成功运行的例子,慢慢掌握原理。
切忌不要根据接口的命名主观的臆断使用方法,结果会很惨的。
yaoxing25
发表于 2009-7-10 01:51:47
谢谢,各位的建议,你们给我的建议真的帮了我很多,对于run_event_loop()退出的想法也是我昨天晚上想到的,今天试了一下,对两个线程加上同步锁就解决了。现在主要的瓶颈是数据库插入操作,太耗时间了,因为我们使用了开发平台中的一个数据库操作,再优化一下数据库的问题应该就可以了,如果再有新的问题,再向大家请教!~再次感谢大家的帮助。等过了这段时间,有空我也会把我使用ACE的心得整理一下,大家共同研究。。。。。