peakzhang 发表于 2008-7-15 22:50:26

Proactor中调用delete this 框架报错?

最近在用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();报错,好像是提示内存有误
由于小弟水平有限,不知这样的问题该如何解决,请教各位大虾了,不啻感激!

peakzhang 发表于 2008-7-15 22:50:33

这是因为你调用 delete 后,ACE_Proactor::instance()->proactor_run_event_loop();还在使用你的 handler 类中的消息块引起的,你必须保证在这些消息块都被回调完后,再被删除,

好好看一下ACE的例子,会有帮助的

peakzhang 发表于 2008-7-15 22:50:43

我刚刚碰见一个这样的问题,解决方案就是,进行线程的同步。保证在delete前,相关的线程肯定退出了。就一定不会有问题

peakzhang 发表于 2008-7-15 22:50:52

如何才能保证相关的线程肯定都退出了呢?我在Delete之前已经加了线程互斥,但问题依然存在, 在这个程序中我在一条连接的handle_read_stream中将收到的消息块直接调用另外一条链路Handler的异步Write方法,请问这样的设计是否合理(曾经考虑过把每条连接都对应一个Queue,Handler收到消息以后就把数据放到另外一个连接的队列中,把两个Handler之间的耦合通过队列隔开?)

peakzhang 发表于 2008-7-15 22:51:04

对此 handler 类设置一个读写计数,当此计数器的值为0时再退出即可

peakzhang 发表于 2008-7-15 22:51:12

就是经常使用的引用计数的技术。非常方便的。

peakzhang 发表于 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?

peakzhang 发表于 2008-7-15 22:51:29

用监控线程?那不是成了垃圾收集了么,效率多差呀。
办法是很简单的,你学过COM没有,其实就是用COM的引用计数的技术,给对象设置一个AddRef和Release方法,只要调用了对象的方法,就AddRef,结束操作就Release,在Release里面,发现引用计数成为0,则delete this,肯定不会出错。
需要注意的要点:
1、引用计数是一个变量,初始值最好是1而不是0,你想想为什么。
2、操作引用计数,一定要增加多线程保护,而且Release里面,不可以使用ACE_GUARD宏。

peakzhang 发表于 2008-7-15 22:51:40

在对象的方法中设置AddRef和Release机制恐怕够戗,因为调用Handler对象成员ACE_Asynch_Write_Stream的Write或ACE_Asynch_Read_Stream的read方法是异步的,调用立刻就会返回,那只是通知框架需要做一个对应的操作,是否需要对这个操作进行统计?

peakzhang 发表于 2008-7-15 22:51:45

你理解错误,不是在异步读写的时候处理引用计数,而是在数据收取完毕后的处理中使用。
页: [1] 2
查看完整版本: Proactor中调用delete this 框架报错?