为简化起见,这是一种NamedPipe SERVER正在等待NamedPipe CLIENT写入管道的情况(使用WriteFile())
阻止的Windows API是ReadFile()
服务器已创建同步管道(没有重叠的I/O)并启用了阻塞
客户端已连接,现在服务器正在等待一些数据.
在正常的事物流中,客户端发送一些数据,服务器处理它,然后返回ReadFile()以等待下一个数据块.
同时发生一个事件(例如用户输入),并且NamedPipe SERVER现在必须执行一些其他代码,当ReadFile()阻塞时,它不能执行.
此时我需要提一下,NamedPipe客户端不是我的应用程序,所以我无法控制它.我不能让它发送几个字节来解锁服务器.它只是坐在那里,不发送数据.由于我无法控制客户端实现,因此我无法更改任何内容.
一种解决方案是创建一个单独的线程,其中执行所有ReadFile()操作.这样,当事件发生时,我可以只处理代码.问题在于,事件还需要一个单独的线程,所以现在我为这个服务器的每个实例都有两个额外的线程.由于这需要可扩展,因此这是不合需要的.
从我试过调用的另一个线程
DisconnectNamedPipe()
和
CloseHandle()
它们都不会返回(直到客户端写入管道.)
我无法连接到同一个管道并写入几个字节,因为:
"命名管道的所有实例共享相同的管道名称,但每个实例都有自己的缓冲区和句柄,并为客户端/服务器通信提供单独的管道."
http://msdn.microsoft.com/en-us/library/aa365590.aspx
我需要一种方法来伪造它,所以$ 64k美元的问题是:
如何打破ReadFile()的阻塞?
在ReadFile之前尝试这个:
BOOL WINAPI PeekNamedPipe( __in HANDLE hNamedPipe, __out_opt LPVOID lpBuffer, __in DWORD nBufferSize, __out_opt LPDWORD lpBytesRead, __out_opt LPDWORD lpTotalBytesAvail, __out_opt LPDWORD lpBytesLeftThisMessage ); if(TotalBytesAvail > 0) ReadFile(....);
-AV-
看看CancelSynchronousIo
将指定线程发出的等待同步I/O操作标记为已取消.
和CancelIo/CancelIoEx:
要取消所有挂起的异步I/O操作,请使用以下任一操作:
CancelIo - 此函数仅取消调用线程为指定文件句柄发出的操作.
CancelIoEx - 此函数取消线程为指定文件句柄发出的所有操作.
http://msdn.microsoft.com/en-us/library/aa363794(VS.85).aspx
http://msdn.microsoft.com/en-us/library/aa365467(VS.85).aspx