【问题标题】:Is there a buffer size attached to stdout?是否有附加到标准输出的缓冲区大小?
【发布时间】:2011-01-05 04:37:22
【问题描述】:

我正在尝试查找与 Windows 上的标准输出相关的数据限制的一些信息。我在 MSDN 上似乎找不到相关信息。

  1. 可以将多少数据写入标准输出是否有限制?如果是这样,如果达到限制会发生什么?数据是否丢失?

  2. 如果 stdout 被重定向(例如,通过从 .Net 启动进程并使用 ProcessStartInfo.RedirectStandardOutput 属性),这对可以写入多少数据有影响吗?当我在调用过程中从标准输出流中读取时,这会影响限制吗?

  3. 这些限制是否与命名管道有任何关系?

【问题讨论】:

    标签: .net windows buffer stdout


    【解决方案1】:

    stdout 有一个 1024 字节的缓冲区

    【讨论】:

    • 你有这个声明的来源吗?
    【解决方案2】:

    注意事项:

    1) Jon 是对的 - 如果达到缓冲区限制,子进程中的写入调用将阻塞。如果 stdout 流没有被重定向到会导致它自动耗尽的地方——比如文件,你需要耗尽它。管道需要排空,通常,如果您可以“附加”到子流程的输出,那么您就是在附加到管道上。

    2) 输出流的 I/O可能被缓冲了,这意味着如果子进程在没有显式调用 flush() 的情况下将一些信息写入标准输出,几乎总是这样,你可能看不到输出。当进程退出时会自动调用 Flush,所以如果它是一个简短的小子进程,你应该没问题,但如果不是,你没有真正的方法来强制它的输出在你想要的时候显示。

    3) 命名管道本质上是操作系统维护的一个可以写入和读取的缓冲区 - 也就是说,它们就像一个文件,您可以从一个进程写入并从另一个进程读取,而实际上没有在磁盘上有文件的开销。对于进程之间的通信非常方便,但所有缓冲/完整缓冲区的 I/O 限制仍然适用。

    【讨论】:

      【解决方案3】:

      这取决于它的去向——但是是的,如果您在 .NET 中重定向输出,如果您不阅读输出,您很容易遇到问题。当缓冲区用完时,子进程中对 stdout 的写入将被阻塞。死锁的一个常见原因是“父”进程等待“子”退出,然后读取输出 - 如果子需要父进程读取输出以释放缓冲区空间,则该进程将不起作用。

      .NET 允许使用 Process.OutputDataReceivedProcess.ErrorDataReceived 的事件驱动方法,使这变得稍微容易一些。这意味着您不需要启动两个线程(一个用于读取 stdout,一个用于读取 stderr)只是为了防止进程阻塞...

      【讨论】:

      • 这比我发布的内容更有帮助。删除我自己的帖子广告投票给你。
      • 现在这是一个方便的功能。我想知道 Java 是否有一天会添加类似的东西。
      • (+1) 拥有 .NET 视角可能更有用,因为我确信所做的决定是为了简化程序员的工作——尽管 stdout 在C 也是如此。
      • 酷,谢谢!在Win32环境下是一样的吗?例如,如果我从命令行运行“process1.exe | process2.exe”,process1 将能够写入 stdout 直到缓冲区已满,然后会阻塞直到 process2 读取足够的数据以便它可以再次写入?我在 MSDN 上没有看到任何关于此的信息。它在缓冲区大小等的任何地方都可用吗?
      • 当子进程以 System.Diagnostics.Process 启动并重定向 stderr 和 stdout 时,我们如何在 PowerShell 中使用它?
      猜你喜欢
      • 2018-12-12
      • 1970-01-01
      • 2012-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-24
      相关资源
      最近更新 更多