当前位置:  开发笔记 > 编程语言 > 正文

打破ReadFile()阻塞 - 命名管道(Windows API)

如何解决《打破ReadFile()阻塞-命名管道(WindowsAPI)》经验,为你挑选了2个好方法。

为简化起见,这是一种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()的阻塞?



1> 小智..:

在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-



2> alex2k8..:

看看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

推荐阅读
地之南_816
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有