【问题标题】:Pipe stalls with I/O redirection带有 I/O 重定向的管道停顿
【发布时间】:2018-04-12 20:59:57
【问题描述】:

我们正在尝试向 ooRexx 编程语言添加一项功能,该功能允许程序员使用标准输入、标准输出和标准错误流上的 I/O 重定向选项发出操作系统命令。我们对 Windows 和所有基于 unix 的系统都这样做。

我们有两种环境的设置,并且设置大致相同:

  1. 为请求的重定向创建适当的管道。
  2. 启动一个新进程来处理该命令。
  3. 将输入数据写入标准输入管道。
  4. 从 stdout 管道读取,然后从 stderr 管道读取。

当有大量数据写入输入管道以及大量输出数据时,我们会遇到停顿问题。如果在写入标准输入时管道已满,我们就会被阻塞。但是,如果启动的进程也设法填满输出管道,它也会阻塞。结果,整个管道停止,一切都挂起。我们的代码一直试图写入输入管道,直到从中读取一些数据。该进程一直试图写入输出管道,直到读取了一些数据,这不会发生,因为对输入的写入已停止。经典的致命拥抱。

我在 Windows 和 Linux 上研究了许多用于非阻塞 I/O 的不同选项,但到目前为止,还没有发现任何不会导致其他问题的方法,例如丢失数据。有人对如何管理有任何建议吗?

对于感兴趣的,这里是处理Windows端的代码的链接:

https://sourceforge.net/p/oorexx/code-0/HEAD/tree/sandbox/rick/addresswith/interpreter/platform/windows/SystemCommands.cpp

这是Linux版本

https://sourceforge.net/p/oorexx/code-0/HEAD/tree/sandbox/rick/addresswith/interpreter/platform/unix/SystemCommands.cpp

【问题讨论】:

  • 你为什么要标记这个 rexx

标签: linux windows pipe rexx


【解决方案1】:

在其文档中似乎是 python documents a similar type of deadlock。似乎python's source code(参见第 900 行和_communicate)通过创建多个读取器守护线程来处理这个问题,当communicate 方法在写入输入管道时从输出管道读取数据被调用。

虽然这种类型的构造是为高级语言(Python)完成的,但我认为创建线程来读取输出管道,同时在主程序中写入输入管道将是一个好方法.虽然,我并没有真正在 C++/C 中使用过线程,所以我不能真正保证它的效率或使用线程时可能存在的任何陷阱。

使用多线程时我可能会看到一个问题(一如既往),您必须确保通过放置适当的同步代码来解决任何可能的数据争用。

【讨论】:

  • 至少在 Windows 上,我已经设法通过为输入端分离一个线程来使其工作。还没有在 Linux 上尝试过。
  • 这是“运行操作系统命令”问题的规范答案。除非您的编程环境为您执行此操作,否则您总是会创建单独的执行环境(线程、进程,无论需要什么)来将 STDIN 提供给命令并使用 STDOUT 和 STDERR。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-23
  • 1970-01-01
  • 2010-09-08
相关资源
最近更新 更多