代码之家  ›  专栏  ›  技术社区  ›  Oleg Zhylin

未缓冲的createnamedpipe用作createprocess的stdout

  •  4
  • Oleg Zhylin  · 技术社区  · 16 年前

    我想执行任意命令行应用程序,并在生成时读取其标准输出。我用 CreateNamedPipe 创建管道,然后供应另一端(打开使用 CreateFile CreateProcess .如果目标进程没有使用标准输出缓冲显式地进行操作,是否有一种方法可以确保有问题的管道没有缓冲,或者至少系统最小值用作缓冲区大小?

    1 回复  |  直到 14 年前
        1
  •  4
  •   Tim Sylvester    16 年前

    您不能真正控制缓冲区大小。您可以将大小为1的读写缓冲区传递给 CreateNamedPipe 但是内核会自动增加这些缓冲区的大小。基本上,缓冲区总是至少和在任何给定时间准备读取的最大数据量一样大。换句话说,对可用数据的响应越快,写入管道的数据块越小,缓冲区将保持越小。

    输入和输出缓冲区大小是建议性的。为命名管道的每一端保留的实际缓冲区大小是系统默认值、系统最小值或最大值,或者指定的大小向上舍入到下一个分配边界。…每当发生管道写入操作时,系统首先尝试根据管道写入配额向内存充电。…如果剩余的管道写入配额太小,无法满足请求,系统将尝试使用为进程保留的非分页池扩展缓冲区以容纳数据。

    但是,我认为缓冲区的大小并不重要。管道不会延迟数据的发送,直到缓冲区“满”,并且没有任何东西可以与TCP的“nagle”选项等效,因此保持较小的缓冲区大小不会提高延迟。

    请记住,将管道连接到控制台应用程序的 stdout ,输出通常由该应用程序进行缓冲。 之前 它写在管道上。如果需要未缓冲的输出,则需要使用stderr。

    另外,在使用继承的管道句柄时要注意的一点是,生成的应用程序将继承您的所有句柄,因此如果打开了一个文件或套接字,您将生成一个应用程序,然后关闭该句柄,文件/套接字等将保持打开状态,直到生成的子进程停止,这可能导致意外的共享冲突,以及其他奇怪的问题。