命名管道类型、读取和等待模式

管道服务器在 CreateNamedPipe 函数的 dwPipeMode 参数中指定管道类型模式、读取模式和等待模式。 管道客户端可以使用 CreateFile 函数为其管道句柄指定这些管道模式。

类型模式

管道的类型模式确定如何将数据写入命名管道。 可以通过命名管道以字节流或消息流的形式传输数据。 在调用 CreateNamedPipe 创建命名管道实例时,管道服务器指定管道类型。 对于管道的所有实例,类型模式必须相同。

若要创建字节类型管道,请指定PIPE_TYPE_BYTE或使用默认值。 数据作为字节流写入管道,系统不会区分以不同写入操作写入的字节。

若要创建消息类型管道,请指定PIPE_TYPE_MESSAGE。 系统会将每个写入操作中写入管道的字节视为消息单元。 系统始终对消息类型管道执行写入操作,就像启用了直通写模式一样。

读取模式

管道的读取模式决定了如何从命名管道读取数据。 管道服务器在调用 CreateNamedPipe 时指定管道句柄的初始读取模式。 可以在字节读取模式或消息读取模式下读取数据。 字节类型管道的句柄只能处于字节读取模式。 消息类型管道的句柄可以处于字节读取或消息读取模式。 对于消息类型管道,对于同一管道实例的服务器句柄和客户端句柄,读取模式可能不同。

若要在字节读取模式下创建管道句柄,请指定PIPE_READMODE_BYTE或使用默认值。 数据作为字节流从管道中读取。 读取管道中的所有可用字节或读取指定数量的字节时,读取操作将成功完成。

若要在消息读取模式下创建管道句柄,请指定PIPE_READMODE_MESSAGE。 数据作为消息流从管道中读取。 仅当读取整个消息时,读取操作才会成功完成。 如果要读取的指定字节数小于下一条消息的大小,则函数在返回零之前读取尽可能多的消息, (GetLastError 函数返回ERROR_MORE_DATA) 。 可以使用另一个读取操作读取消息的其余部分。

对于管道客户端, CreateFile 返回的管道句柄最初始终处于字节读取模式。 管道客户端和管道服务器都可以使用 SetNamedPipeHandleState 函数更改管道句柄的读取模式。 管道句柄必须具有FILE_WRITE_ATTRIBUTES访问权限。

等待模式

管道句柄的等待模式确定 ReadFileWriteFileConnectNamedPipe 函数如何处理冗长操作。 在阻塞等待模式下,函数无限期地等待管道另一端的进程完成操作。 在非阻止等待模式下,函数在需要无限期等待的情况下立即返回。

当管道为空时, ReadFile 操作受管道句柄的等待模式的影响。 使用阻塞等待句柄时,在线程写入管道另一端的数据可用之前,操作不会成功完成。 使用非阻止等待句柄,函数立即返回零, GetLastError 函数返回ERROR_NO_DATA。

当管道的缓冲区中空间不足时, WriteFile 操作受管道句柄的等待模式的影响。 使用阻塞等待句柄时,在从管道另一端读取的线程在缓冲区中创建足够的空间之前,写入操作无法成功。 使用非阻止等待句柄时,写入操作将立即返回非零值,无需为消息类型管道) 写入任何字节 (,也不会写入缓冲区保留的字节数 (字节类型管道) 。

当没有客户端连接或等待连接到管道实例时, ConnectNamedPipe 操作受管道句柄的等待模式的影响。 使用阻塞等待句柄时,在管道客户端通过调用 CreateFileCallNamedPipe 函数连接到管道实例之前,连接操作不会成功。 使用非阻止等待句柄时,连接操作将立即返回零, GetLastError 函数返回ERROR_PIPE_LISTENING。

默认情况下, CreateNamedPipeCreateFile 函数返回的所有命名管道句柄都是在启用阻止等待模式的情况下创建的。 若要在非阻止等待模式下创建管道,管道服务器在调用 CreateNamedPipe 时指定PIPE_NOWAIT。

管道客户端和管道服务器都可以通过在对 SetNamedPipeHandleState 函数的调用中指定PIPE_WAIT或PIPE_NOWAIT来更改管道句柄的等待模式。

注意

支持非阻止等待模式,以便与 Microsoft LAN Manager 版本 2.0 兼容。 不应使用此模式来实现具有命名管道的 I/O) (重叠的输入和输出。 应改用重叠的 I/O,因为它允许在函数返回后在后台运行耗时的操作。 有关重叠 I/O 的详细信息,请参阅 同步和重叠输入和输出