找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 9964|回复: 13

Proactor中调用delete this 框架报错?

[复制链接]
发表于 2008-7-15 22:50:26 | 显示全部楼层 |阅读模式
最近在用ACE Proactor框架写一个类似于Proxy的程序,在内网和外网之间转发数据包,但是发现当内网Socket断开以后,程序回调handle_read_stream函数中,此时我Delete外网对应的Handler(断掉外网的TCP连接)和内网的Handler,继续执行Proactor框架报错,具体情况如下:
     比如:
      在handle_read_stream中 delete internalHandler; delete externalHandler;后
   程序在 ACE_Proactor::instance()->proactor_run_event_loop();报错,好像是提示内存有误
由于小弟水平有限,不知这样的问题该如何解决,请教各位大虾了,不啻感激!
 楼主| 发表于 2008-7-15 22:50:33 | 显示全部楼层
这是因为你调用 delete 后,ACE_Proactor::instance()->proactor_run_event_loop();还在使用你的 handler 类中的消息块引起的,你必须保证在这些消息块都被回调完后,再被删除,

好好看一下ACE的例子,会有帮助的
 楼主| 发表于 2008-7-15 22:50:43 | 显示全部楼层
我刚刚碰见一个这样的问题,解决方案就是,进行线程的同步。保证在delete前,相关的线程肯定退出了。就一定不会有问题
 楼主| 发表于 2008-7-15 22:50:52 | 显示全部楼层
如何才能保证相关的线程肯定都退出了呢?我在Delete之前已经加了线程互斥,但问题依然存在, 在这个程序中我在一条连接的handle_read_stream中将收到的消息块直接调用另外一条链路Handler的异步Write方法,请问这样的设计是否合理(曾经考虑过把每条连接都对应一个Queue,Handler收到消息以后就把数据放到另外一个连接的队列中,把两个Handler之间的耦合通过队列隔开?)
 楼主| 发表于 2008-7-15 22:51:04 | 显示全部楼层
对此 handler 类设置一个读写计数,当此计数器的值为0时再退出即可
 楼主| 发表于 2008-7-15 22:51:12 | 显示全部楼层
就是经常使用的引用计数的技术。非常方便的。
 楼主| 发表于 2008-7-15 22:51:19 | 显示全部楼层
初步设想在调用Handler的read和write提交异步操作之前使Handler的计数加一,在handle_read_stream和handle_write_stream中使计数减一,当在handle_read_stream中检测到连接断开以后首先调用shutdown和closesocket关闭本端的Socket连接,然后调用当前Handler的Cancel方法取消已经提交车操作,再判断当前Handler计数是否大于一(如果大于一表明还有线程对Handler作引用),如果等于0,则执行delete this并返回

请问大家这样的思路不知是否可行,另外如果当前Handler计数不为0,那么delete这个Handler的操作应该从哪处来完成呢?是否还需要启动另外一个监视线程定时判断Handler计数是否为0,若为0则从监视线程delete该Handler?
 楼主| 发表于 2008-7-15 22:51:29 | 显示全部楼层
用监控线程?那不是成了垃圾收集了么,效率多差呀。
办法是很简单的,你学过COM没有,其实就是用COM的引用计数的技术,给对象设置一个AddRef和Release方法,只要调用了对象的方法,就AddRef,结束操作就Release,在Release里面,发现引用计数成为0,则delete this,肯定不会出错。
需要注意的要点:
1、引用计数是一个变量,初始值最好是1而不是0,你想想为什么。
2、操作引用计数,一定要增加多线程保护,而且Release里面,不可以使用ACE_GUARD宏。
 楼主| 发表于 2008-7-15 22:51:40 | 显示全部楼层
在对象的方法中设置AddRef和Release机制恐怕够戗,因为调用Handler对象成员ACE_Asynch_Write_Stream的Write或ACE_Asynch_Read_Stream的read方法是异步的,调用立刻就会返回,那只是通知框架需要做一个对应的操作,是否需要对这个操作进行统计?
 楼主| 发表于 2008-7-15 22:51:45 | 显示全部楼层
你理解错误,不是在异步读写的时候处理引用计数,而是在数据收取完毕后的处理中使用。
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-11-21 20:57 , Processed in 0.018775 second(s), 6 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表