最近发现我的服务器的内存在上涨,经过多次走查代码,终于发现问是所在,我简单描述一下我的应用,望大家帮我解决:
为了提高效率,我为每个连接都保持了1~3个WSASend请求,如果WSASend过快的话,前一个WSASend中事件未决,马上又投递了另一个,这样维持在2个左右。现在有一个问是,就是我监测这些IO投递过程中,发现存在大量未决事件,即使在某处调用了closesocket,那些未决事件仍然未返回,而这些未决事就引起了内存泄漏。我查了大量资料,都是说close后,该连接的所有IO请求都乖乖地返回,可是我却总是没发现有返回呢?
(注,我是通过ByteTransferred == 0来判断是否返回的,正确吗?)困惑了很久,指望你们了!
为了提高效率,我为每个连接都保持了1~3个WSASend请求,如果WSASend过快的话,前一个WSASend中事件未决,马上又投递了另一个,这样维持在2个左右。现在有一个问是,就是我监测这些IO投递过程中,发现存在大量未决事件,即使在某处调用了closesocket,那些未决事件仍然未返回,而这些未决事就引起了内存泄漏。我查了大量资料,都是说close后,该连接的所有IO请求都乖乖地返回,可是我却总是没发现有返回呢?
(注,我是通过ByteTransferred == 0来判断是否返回的,正确吗?)困惑了很久,指望你们了!
我在观察到这个现象后,我使程序不再投递WSASend,也就是说,如果某个连接存在2个未决事件后不再往这个连接WSASend,很长时间或永远,或close该连接后,那2个未决事件一直都没有返回。
http://topic.csdn.net/u/20091209/13/0594ef65-5ae2-4c4e-a30d-2565f6f49387.html
也就是说,close后,并不能通过ByteTransferred == 0来判断返回,而是GET失败表示close的返回吗?
一般情况绝对是会返回的.
这个成功是指成功入队,理论上可以被GET到事件了,而不是指数据发送成功!
通过WSAGetLastError获得错误代码,如果是ERR_IO_PEEDING的话,那就能够保证数据入队了
你说的完成端口句柄是指关联的socket吗?
CreateIoCompletionPort((HANDLE)hSocket,
CompletionPort,
(DWORD)pPerHandleData,
0);就是因为有未决操作,所以我要close啊,如果有未决就不能close,那不是死循环了?
对头,但不是所有GET都表示CLOSE,如果GET到一个错误值,你需要再投递一次相应的操作,如果此时出错那么就表示真的出错了.或是取一下WSAGetlsatError()值来判断否真的出错.然后再去处理相应的动作.
处理异步事,通常做法是,发送通知,然后等待返回.
如果投递了N多事件,这时要退出,那么只要关闭所有句柄,那么所有未决事件都会返回(也就是GET到).这样走正常出错处理就可以了.
这之后你就要想法等待所有未决事件都处理完后,退出IO线程(也就GET的那个线程,用POST就行).
再之后就是句柄回收的工作,什么完成端口,线程句柄,内存对象,事件对象,等等一切...
不是 “关联的socket”是 你的“CompletionPort”
如果你一定要投递超过一个以上的WSASend(),弄个计数,WSASend()投递后就加1,WSASend()发送完所有数据就减1.程序退出时就检查每个socket的计数都是为0,如果大于0,那肯定还有没完成的。
shenyi0106
(紫色清风) 等 级:
#10楼 得分:100回复于:2009-12-09 16:02:42如需要阅读该回复,请登录或注册CSDN!
======================================
为什么我看不见?