Winapi windows中的命名管道,文件\u标志\u重叠和管道\u NOWAIT之间的差异

Winapi windows中的命名管道,文件\u标志\u重叠和管道\u NOWAIT之间的差异,winapi,ipc,named-pipes,overlap,Winapi,Ipc,Named Pipes,Overlap,我在windows中使用命名管道,对重叠的FILE\u FLAG\u和pipe\u NOWAIT之间的区别感到困惑,这是在CreateNamedPipe中设置的参数,我设置的参数如下 HANDLE hPipe = CreateNamedPipe( lpszPipename, // pipe name PIPE_ACCESS_DUPLEX | // read/write access FILE_FLAG_OVERLAPPED,

我在windows中使用命名管道,对重叠的
FILE\u FLAG\u
pipe\u NOWAIT
之间的区别感到困惑,这是在
CreateNamedPipe
中设置的参数,我设置的参数如下

HANDLE hPipe = CreateNamedPipe(
    lpszPipename,             // pipe name 
    PIPE_ACCESS_DUPLEX |      // read/write access 
    FILE_FLAG_OVERLAPPED,     // overlapped mode 
    PIPE_TYPE_MESSAGE |       // message-type pipe 
    PIPE_READMODE_MESSAGE |   // message read mode 
    PIPE_WAIT,                // blocking mode 
    PIPE_UNLIMITED_INSTANCES, // unlimited instances 
    BUFSIZE * sizeof(TCHAR),    // output buffer size 
    BUFSIZE * sizeof(TCHAR),    // input buffer size 
    PIPE_TIMEOUT,             // client time-out 
    NULL);                    // default security attributes
ConnectNamedPipe
立即返回,我从
GetLastError
获得
ERROR\u IO\u PENDING
。使用非阻塞等待句柄,连接操作立即返回零,GetLastError函数返回
ERROR\u IO\u PENDING
。但是MSDN告诉: 使用非阻塞等待句柄时,connect操作立即返回零,GetLastError函数返回ERROR\u PIPE\u listing。
那么,
nonblocking wait
是什么意思,
PIPE\u NOWAIT
FILE\u FLAG\u重叠
,非常感谢

PIPE\u NOWAIT
表示在句柄上启用了非阻塞模式。在此模式下,
ReadFile
WriteFile
ConnectNamedPipe
始终立即完成

文件标志重叠
表示在句柄上启用异步模式。如果启用此模式,所有非同步io[1]操作总是立即返回

因此
文件\u标志\u重叠
vs
管道\u NOWAIT
-这是立即返回vs立即完成

立即完成(包括立即返回)表示在api返回时io操作已经完成。但事实并非如此。如果操作立即返回,这并不意味着操作已经完成。如果操作仍未完成,ntapi返回代码
状态\u挂起
。win32 api在这种情况下通常将最后一个错误设置为
error\u IO\u PENDING

在异步处理模式下,存在3路确定io操作何时完成

  • 将句柄绑定到IOCP(通过
    CreateIoCompletionPort
    BindIoCompletionCallback
    CreateThreadpoolIo
    )。结果当 io完成-指向重叠的
    指针,我们将其传递给io调用-
    将排队返回IOCP(如果
    BindIoCompletionCallback
    CreateThreadpoolIo
    系统自己创建IOCP并监听它 当指向重叠的
    指针将
    排队到IOCP)
  • 一些win32 api,如
    ReadFileEx
    WriteFileEx
    和所有ntapi 指定将在上下文中调用的APC完成例程 当io操作完成时开始io操作的线程。 在这种情况下,线程必须执行可警报的等待。这不是等待 与绑定句柄到IOCP兼容(我们不能在中使用APC例程) 如果文件句柄绑定到IOCP,则调用api-系统返回无效 参数错误)
  • 我们可以创建事件并将其传递给api调用(通过
    OVERLAPPED::hEvent
    )-在这种情况下,此事件将由 io操作开始时的系统,并在io运行时设置为信号状态 操作完成。与本例中的前2个选项不同,我们有 io时没有其他上下文(指向
    的面指针重叠
    ) 操作完成。通常这是最糟糕的选择

  • [1] 存在一些始终是同步api的io操作。例如
    GetFileInformationByHandleEx
    SetFileInformationByHandle
    。但几乎所有io操作都不是同步io。所有这些io操作都将指向重叠的
    的指针作为参数。所以,如果api签名中没有指向重叠的
    的指针,这就是同步api调用。如果存在-通常是异步的(异常
    CancelIoEx
    ,例如,指向重叠的指针与当前操作无关,而是与我们希望取消的前一个io操作有关)。特别是
    ReadFile
    WriteFile
    DeviceIoControl
    ConnectNamedPipe
    (在内部,这是调用
    DeviceIoControl
    FSCTL\u PIPE\u LISTEN
    )不是同步io api

    似乎MSDN在使用
    PIPE\uwait
    时使用了术语“非阻塞模式”,而使用
    FILE\u FLAG\u overlapped
    PIPE\u NOWAIT
    时的“重叠模式”是非常不同的选项。FILE\u FLAG\u overlapped设置套接字以便它可以处理异步I/O,您可以调用ReadFile()使用重叠参数并稍后处理读取完成。这对于管道非常常见,除非流量非常高,否则您希望避免过多地阻塞线程。PIPE_NOWAIT对于同步I/O非常有用,它可以防止ReadFile()在没有数据时阻塞。重复调用ReadFile()然后是必需的,用通用术语进行轮询。