【问题标题】:Cross-platform (linux/Win32) nonblocking C++ IO on stdin/stdout/stderrstdin/stdout/stderr 上的跨平台 (linux/Win32) 非阻塞 C++ IO
【发布时间】:2010-09-23 19:51:14
【问题描述】:

我正在尝试通过具有以下特征的标准输入/标准输出找到非阻塞 IO 的最佳解决方案:

  • 只要有足够的数据,就读入 n 大小的块。
  • 如果数据不足,则读入部分块。
  • 如果没有可用数据,则阻塞直到有一些数据(即使它可能小于 n)。

目标是允许在立即处理“控制”代码的同时高效传输大型数据集(而不是让它们停留在某个部分填充的缓冲区中)。

我知道我可以通过使用线程和 istream::get() 循环来实现这一点,或者通过编写一堆特定于平台的代码(因为您不能 select() 在 Windows 中的文件句柄上)... ((还有 istream::readsome() 似乎很有希望,但我在谷歌上能找到的唯一结果是人们说它实际上并不好用。))

由于我没有使用这些 API 编写过多代码,也许有更好的方法。

【问题讨论】:

    标签: c++ pipe stdin iostream nonblocking


    【解决方案1】:

    也许boost::asio 对你有用?

    【讨论】:

    • 这看起来很有前途(一个小问题的大锤,但可能值得学习)......谢谢!
    • 是的,这可能是可移植异步 I/O 的最佳选择,因为该语言没有对非阻塞 I/O 线程的原生支持。您必须使用某种库,而 boost 通常是一个不错的选择。
    • (如果只有 Win32 支持任意句柄上的 select() 或 poll() 而不仅仅是套接字)...在进行了一些挖掘之后,我已经确认我可以做我需要的,甚至还有设置教程:highscore.de/boost/process/process/…
    • 附录:本教程用于使用异步流捕获子进程的标准输入/标准输出;我想要的是让我自己的进程以异步方式处理自己的 stdin/stout。尽管如此,这仍然是一个不错的 90%。
    • @DanS.:你有没有找到 100% 的解决方案?我现在是trying to solve the same problem
    【解决方案2】:

    我使用了线程和平台特定的代码。见my answer to another question。我能够将特定于操作系统的东西放在 inputAvailable() 中(Linux 使用 select,Windows 只返回 true)。然后我可以在 Windows 上使用带有超时的 WaitForSingleObject() 来尝试让线程完成,然后使用 TerminateThread() 来杀死它。非常难看,但团队不想使用这种提升。

    【讨论】:

    • 这仅链接到非跨平台解决方案(还包括一些陈旧的链接)。你有原始的实现吗?
    • 对不起,那是一家过去的公司,我不再有那个代码了。我相信inputAvailable() 的代码是Linux 解决方案。查看 _kbit() 作为 Windows 的起点:docs.microsoft.com/en-us/cpp/c-runtime-library/reference/…
    【解决方案3】:

    我做了类似于 jwhitlock 的事情......我最终得到了一个 StdinDataIO 类,它围绕适当的操作系统特定实现(*),以便我的程序的其余部分可以在 StdinDataIO 提供的文件描述符上选择(),剩下的幸福地无知 Windows 对标准输入的限制。如果你愿意,看看herehere,代码都是开源/BSD 许可的。

    (*) 该实现是 Linux/MacOSX 的简单传递,而在 Windows 中,这是一个相当复杂的过程,即设置子线程以从标准输入读取数据并将其通过套接字接收到的数据发送回主线程线程......不是很优雅,但它有效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-05
      • 2012-02-07
      相关资源
      最近更新 更多