完成端口,释放资源问题

在完成端口线程中,只有单个Read操作,在Read失败或者投递Read失败,就释放对应资源,
如果频繁的执行连接,发送数据,断开,这一系列操作,就会出现heap free .....之类的错误
使用WINDBG查看内存信息,确实是在释放之后,原来的ol结构又被系统修改了值使用了。

PS:对象的申请和释放都是加锁的。

是否有可解决的方案???

作者: xyz378704   发布时间: 2011-06-15

采用内存池方案。。。

作者: VisualEleven   发布时间: 2011-06-15

一个是内存池
还有一个是释放结构时,做个标记,防止重复释放

作者: shenyi0106   发布时间: 2011-06-15

引用 1 楼 visualeleven 的回复:
采用内存池方案。。。


这个是必须的么?如果采用内存池,是否会有影响,而且,也不好暴露更多的问题。
请问WINDOWS是否真的是在GCQS完成后,还会对ol结构进行修改?

作者: xyz378704   发布时间: 2011-06-15

引用 2 楼 shenyi0106 的回复:
一个是内存池
还有一个是释放结构时,做个标记,防止重复释放


重复释放可定没有,因为加的是CS锁,做标记无意义

作者: xyz378704   发布时间: 2011-06-15

还是资源重用吧,释放改成资源初始化,能节省些CPU,程序也更稳定

作者: mukefei77   发布时间: 2011-06-15

引用 5 楼 mukefei77 的回复:
还是资源重用吧,释放改成资源初始化,能节省些CPU,程序也更稳定


资源重用以后再做,如果不确定原因,难保不会出现问题,

作者: xyz378704   发布时间: 2011-06-15

引用 4 楼 xyz378704 的回复:
引用 2 楼 shenyi0106 的回复:
一个是内存池
还有一个是释放结构时,做个标记,防止重复释放


重复释放可定没有,因为加的是CS锁,做标记无意义

加了CS锁就能保证不重复释放了?
比如你IOCP中维持的链接超时了,你关闭这个socket时,GCS就有可能会出现两次消息,这两次消息所带的IO_BUFFER地址是一样的,请问你如何区分?

作者: shenyi0106   发布时间: 2011-06-15

能描述清楚点么?你的流程是怎么样的。

Read失败或者投递Read失败是什么意思?完成端口,I/O操作不会同步完成的,只能通过GetQueuedCompletionStatus去获取结果的。

作者: kyotrue   发布时间: 2011-06-15

引用 7 楼 shenyi0106 的回复:
引用 4 楼 xyz378704 的回复:
引用 2 楼 shenyi0106 的回复:
一个是内存池
还有一个是释放结构时,做个标记,防止重复释放


重复释放可定没有,因为加的是CS锁,做标记无意义

加了CS锁就能保证不重复释放了?
比如你IOCP中维持的链接超时了,你关闭这个socket时,GCS就有可能会出现两次消息,这两次消息所带的IO_BUFFER地址是一样的,请问……


IOCP中的等待是无限的,并且是使用index来做唯一标识

作者: xyz378704   发布时间: 2011-06-15

你通过index来做唯一标识,保证GetQueuedCompletionStatus后处理时,只将ol释放一次?

作者: kyotrue   发布时间: 2011-06-15

引用 8 楼 kyotrue 的回复:
能描述清楚点么?你的流程是怎么样的。

Read失败或者投递Read失败是什么意思?完成端口,I/O操作不会同步完成的,只能通过GetQueuedCompletionStatus去获取结果的。


大致流程是这个

CreatIoComplete绑定完成建等信息

PostRecv

IOCP线程

GCQS返回后
处理数据继续投递

如果有错,释放资源



作者: xyz378704   发布时间: 2011-06-15

引用 10 楼 kyotrue 的回复:
你通过index来做唯一标识,保证GetQueuedCompletionStatus后处理时,只将ol释放一次?


我只绑定完成建,不投递任何接受或者发送BUF,如果超时,IOCP线程会有通知??

作者: xyz378704   发布时间: 2011-06-15

引用 10 楼 kyotrue 的回复:
你通过index来做唯一标识,保证GetQueuedCompletionStatus后处理时,只将ol释放一次?


通过index在链表中查找,找到了就被移除链表了,

作者: xyz378704   发布时间: 2011-06-15

没用过你那个网络模型,不过你的I/O操作如果用了完成端口,那么除非在你PostRecv时就失败了,不然最终结果肯定会到IOCP线程中处理的。

作者: kyotrue   发布时间: 2011-06-15

就是在PostRecv失败了,因为只有一个PostRecv所以可以安全的释放资源,但是结果却不是这样,郁闷

作者: xyz378704   发布时间: 2011-06-15