线程终止、请求丢失。

本文介绍了一个关于异步IO的问题及其解决方案。作者在编写一个小程序时遇到问题:当使用WSARecv()发起异步请求后,无法获取到数据。通过逐步排查,最终发现是由于发起IO请求的线程提前终止导致数据丢失,并通过使用QueueUserWorkItem()来替代自定义线程解决了该问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天写一个小程序,当接收到指定消息时,创建一个SOCKET去连接指定主机,一旦接通,就向主机发送、以及从主机取回一些数据。为了避免阻塞,每当需要连接主机的时候,就创建一个线程,在该线程里调用connect(),连接成功后就用send()发送一些数据,紧接着调用WSARecv()发起一个overlapped的异步取请求,然后线程退出。
结果是,负责监视完成端口的线程,根本取不到数据,只是收到一个SOCKET断开的事件。没办法,只好单步跟踪,奇怪的是,单步跟踪时居然一切正常,该发送的数据发送了,该收到的数据也收到了,百思不得其解……加上一些调试信息,发现WSARecv()会返回WSA_IO_PENDING,这个返回值表示重叠IO已提交,但暂时没有还完成……这个返回值也属于正常情况,但偏偏就是收不到数据。< /div>
想起单步跟踪时,一切都正常,而单步跟踪与正常运行的唯一差别,可以说就是单步跟踪时执行每条语句时有延时,于是在WSARecv()前面加上一条Sleep(1000),再运行程序,惊奇地发现数据收到了,而调试信息打印的WSARecv()返回值是 0……
为什么有了延时就会成功呢,左思右想,忽然从脑海深处闪出一条很久以前的记忆:当发起IO请求的线程终止后,该IO请求将被Windows丢弃!心中一阵狂喜,几乎可以肯定就是这个原因了,马上修改代码,用QueueUserWorkItem()并且传递 WT_EXECUTEINIOTHREAD参数来取代自己创建的线程,运行后果然一切正常。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值