Winapi 命名管道和重叠在窗口上

Winapi 命名管道和重叠在窗口上,winapi,named-pipes,Winapi,Named Pipes,我将要实现我的第一个Windows服务。该服务将连接到蓝牙加密狗,并将一些命令和数据连接到单个客户端进程。 每个进程(客户机、服务器)应至少有两个线程-一个阻塞Read(),另一个处理业务逻辑,偶尔执行Write() 检查备选方案后,我决定使用IPC,但我在理解某些设置时遇到了困难。具体而言: 我希望允许同时读写。即使我不打算在同一个线程上执行读写操作,我是否需要使用创建管道 如果上面的答案是“是”,我是否仍然需要将重叠的结构传递给、使用等?如果是的话,这背后的理性是什么 让一个线程执行非阻塞

我将要实现我的第一个Windows服务。该服务将连接到蓝牙加密狗,并将一些命令和数据连接到单个客户端进程。 每个进程(客户机、服务器)应至少有两个线程-一个阻塞Read(),另一个处理业务逻辑,偶尔执行Write()

检查备选方案后,我决定使用IPC,但我在理解某些设置时遇到了困难。具体而言:

  • 我希望允许同时读写。即使我不打算在同一个线程上执行读写操作,我是否需要使用创建管道
  • 如果上面的答案是“是”,我是否仍然需要将重叠的
    结构传递给、使用等?如果是的话,这背后的理性是什么
  • 让一个线程执行非阻塞读写有什么好处?用例是什么
编辑

我想澄清问题:

  • 假设两个线程(读/写)同时访问管道,由于某些内部管道互斥,一个线程是否会阻塞直到另一个线程完成
  • 设置
    FILE\u FLAG\u OVERLAPPED
    是否会更改此行为

如果您所做的只是同时使用同一个句柄进行读写,则不需要使用文件标志重叠。其他线程读取或写入管道的同一端不会导致管道阻塞。只有当您想要执行异步I/O时才需要它,而您显然不需要

如果确实使用FILE_FLAG_OVERLAPPED,则必须通过lpOverlapped参数将有效的OVERLAPPED结构传递给ReadFile和WriteFile。如果不使用此标志且句柄不可查找(例如,命名管道),则必须传递NULL


与多线程实现相比,使用单线程异步I/O的最大优势在于您不必担心并发问题。如果只有一个线程,就不能有竞争条件和死锁。(实际上,在您的情况下,由于您仍然有两个线程,一个在服务器上,一个在客户端,如果您真的尝试,您仍然可能会出现死锁和竞争条件,但异步I/O仍然可以更容易地避免它们。)

要启用对管道的双向访问,必须为dwOpenMode参数指定标志。启用双向模式不严格要求(
文件\u标志\u重叠

但是,对于双向管道,建议使用异步I/O。它允许您在同一线程上同时执行读写操作(请参阅)。任一操作在完成时发出信号。例如,这可以防止冗长的写操作阻塞潜在的读操作,并且您可以及时响应其中任何一个。也许更重要的是,由于您永远不知道数据何时可用,您通常希望始终发出读取操作,而不让它阻塞您的线程

文件中概述了这一点:

如果启用了[overlapped]模式,则执行读、写和连接操作(可能需要很长时间才能完成)的函数可以立即返回。此模式允许启动操作的线程在后台执行耗时的操作时执行其他操作。例如,在重叠模式下,线程可以在管道的多个实例上同时处理输入和输出(I/O)操作,或者在同一管道句柄上同时执行读写操作。如果未启用重叠模式,则在管道句柄上执行读取、写入和连接操作的函数在操作完成之前不会返回。和函数只能在重叠模式下与管道句柄一起使用。、和函数可以同步执行,也可以作为重叠操作执行


管道已经允许同时读写。如果要使用线程进行读取,则根本不需要重叠的I/O。@HansPassant-谢谢。我想我想问的是:“如果一个线程同时读取,另一个线程同时写入,一个线程是否会阻塞,直到另一个线程完成?”-修复question@bavaza:不同的线程可以同时读写,互不干扰。无论您是否使用异步(重叠)I/O,这都是正确的。我确实希望执行异步I/O,但不希望从单个线程执行。也就是说,在写线程完成之前,我不希望读线程阻塞,反之亦然。@bavaza如果您希望读线程阻塞,直到句柄上有可读取的内容,那么您希望执行同步I/O。正如我所说的,如果您所做的只是从中读取和写入,则不需要使用文件\u标志\u重叠标志同时使用同一个手柄。使用同步I/O时,如果没有要读取的内容,则只读取块;如果管道的缓冲区中没有存储写入内容的空间,则只写入块。其他线程读取或写入到管道的同一端不会导致阻塞。“其他线程读取或写入到管道的同一端不会导致阻塞”-这就是我想要的,谢谢。您可以将其添加到您的答案中吗?是否确实不需要文件\u FLAG\u重叠来读取和写入不同线程中的同一命名管道?我没能做到这一点。@Rick根据文档,这是不可能的:我也试过了,没用。。。线被卡住了。