神奇的ConnectNamedPipe,哪位高手能告诉小弟我它的异步模式的大致实现
神奇的ConnectNamedPipe,谁能告诉我它的异步模式的大致实现?
在使用ConnectNamePipe异步模式的时候,发现一件很神奇的事情,我调试了微软MSDN的代码例子:http://msdn.microsoft.com/EN-US/library/windows/desktop/aa365601(v=vs.85).aspx
明明这个函数调用的时候已经立即返回了,但是在读写回调(CompletedReadRoutine和CompletedWriteRoutine)的时候堆栈却是从这个函数发出的,而且位于主线程当中!而这个时候主线程按道理还在WaitForSingleObjectEx中阻塞着,这到底是什么情况,我凌乱了。。。求高手来给解释。
附完整代码:
在使用ConnectNamePipe异步模式的时候,发现一件很神奇的事情,我调试了微软MSDN的代码例子:http://msdn.microsoft.com/EN-US/library/windows/desktop/aa365601(v=vs.85).aspx
明明这个函数调用的时候已经立即返回了,但是在读写回调(CompletedReadRoutine和CompletedWriteRoutine)的时候堆栈却是从这个函数发出的,而且位于主线程当中!而这个时候主线程按道理还在WaitForSingleObjectEx中阻塞着,这到底是什么情况,我凌乱了。。。求高手来给解释。
附完整代码:
// NamedPipTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <strsafe.h>
#define PIPE_TIMEOUT 5000
#define BUFSIZE 4096
typedef struct
{
OVERLAPPED oOverlap;
HANDLE hPipeInst;
TCHAR chRequest[BUFSIZE];
DWORD cbRead;
TCHAR chReply[BUFSIZE];
DWORD cbToWrite;
} PIPEINST, *LPPIPEINST;
VOID DisconnectAndClose(LPPIPEINST);
BOOL CreateAndConnectInstance(LPOVERLAPPED);
BOOL ConnectToNewClient(HANDLE, LPOVERLAPPED);
VOID GetAnswerToRequest(LPPIPEINST);
VOID WINAPI CompletedWriteRoutine(DWORD, DWORD, LPOVERLAPPED);
VOID WINAPI CompletedReadRoutine(DWORD, DWORD, LPOVERLAPPED);
HANDLE hPipe;
int _tmain(VOID)
{
HANDLE hConnectEvent;
OVERLAPPED oConnect;
LPPIPEINST lpPipeInst;
DWORD dwWait, cbRet;
BOOL fSuccess, fPendingIO;
// Create one event object for the connect operation.
hConnectEvent = CreateEvent(
NULL, // default security attribute
TRUE, // manual reset event
TRUE, // initial state = signaled
NULL); // unnamed event object
if (hConnectEvent == NULL)
{
printf("CreateEvent failed with %d.\n", GetLastError());
return 0;
}
oConnect.hEvent = hConnectEvent;
// Call a subroutine to create one instance, and wait for
// the client to connect.
fPendingIO = CreateAndConnectInstance(&oConnect);
while (1)
{
// Wait for a client to connect, or for a read or write
// operation to be completed, which causes a completion
// routine to be queued for execution.
dwWait = WaitForSingleObjectEx(
hConnectEvent, // event object to wait for
INFINITE, // waits indefinitely
TRUE); // alertable wait enabled
switch (dwWait)
{
// The wait conditions are satisfied by a completed connect
// operation.
case 0:
// If an operation is pending, get the result of the