写完成例程demo时发现一个问题,在这里记录一下。
对完成例程的介绍中,一般书上还有网上的资料代码都会说在投递完成例程后要调用SleepEx()或者类似的函数使线程处于一种警觉的等待状态,这样线程就会去处理自己apc队列里的apc请求,所以我在我的demo中也是这样做的,测试了一下没有问题。但是后来我试着把SleepEx删掉结果也是正常的,这就奇怪了,如果不调用sleepex之类的函数,那么完成例程是怎么被调用的呢,在这个问题困惑了,因为网上的完成例程的代码还有介绍都没有提到这个问题。
demo运行的结果表明完成例程确实被调用了,也就是说线程肯定是已经进入过等待状态,那么是什么代码导致进入这个状态呢,找来找去也就只要accpet有这个可能,因为我写的demo中accept和完成例程是在同一个线程中,所以到msdn上查了一下,果然
Note When issuing a blocking Winsock call such as accept, Winsock may need to wait for a network event before the call can complete. Winsock performs an alertable wait in this situation, which can be interrupted by an asynchronous procedure call (APC) scheduled on the same thread.
也就是accpet导致的线程阻塞实际上是使线程进入了等待状态,一切真相大白。