在stdin/stdout/stderr上跨平台(linux/Win32)不阻塞c++ IO

时间:2021-12-21 12:02:35

I'm trying to find the best solution for nonblocking IO via stdin/stdout with the following characteristics:

我正试图通过stdin/stdout找到最佳的非阻塞IO的解决方案:

  • As long as there is enough data, read in n-sized chunks.
  • 只要有足够的数据,就可以读取n大小的块。
  • If there's not enough data, read in a partial chunk.
  • 如果没有足够的数据,请读取部分数据块。
  • If there is no data available, block until there is some (even though it may be smaller than n).
  • 如果没有可用的数据,块直到有一些数据(尽管它可能小于n)。

The goal is to allow efficient transfer for large datasets while processing 'control' codes immediately (instead of having them linger in some partially-filled buffer somewhere).

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

I know I can achieve this by using threads and a istream::get() loop, or by writing a bunch of platform-specific code (since you can't select() on file handles in windows)... ((There is also istream::readsome() which seems promising, but the only results I can find on google were of people saying it doesn't actually work well.))

我知道通过使用线程和istream::get()循环,或者编写一组特定于平台的代码(因为在windows的文件句柄上不能选择()),我可以实现这一点。(还有istream: readsome(),看起来很有前途,但我在谷歌上能找到的唯一结果是,人们说它实际上并不好用。)

Since I haven't done much coding w/ these APIs, perhaps there is a better way.

由于我还没有对这些api进行太多的编码,也许还有更好的方法。

3 个解决方案

#1


6  

Maybe boost::asio can be of use for you?

也许boost::asio对你有帮助吗?

#2


1  

I used the threads and platform specific code. See my answer to another question. I was able to put the OS-specific stuff in inputAvailable() (Linux uses select, Windows just returns true). I could then use WaitForSingleObject() with a timeout on Windows to try to let the thread complete, then TerminateThread() to kill it. Very ugly, but the team didn't want to use this bit of boost.

我使用了特定于线程和平台的代码。请看我对另一个问题的回答。我能够将特定于操作系统的内容放入inputAvailable() (Linux使用select, Windows只返回true)中。然后,我可以使用WaitForSingleObject(),在Windows上设置一个超时,以尝试让线程完成,然后终止ethread()来终止它。很丑,但是球队不想用这种刺激。

#3


0  

I did something similar to jwhitlock ... I ended up with a StdinDataIO class that wraps around the appropriate OS-specific implementation(*) so that the rest of my program can select() on the file descriptor StdinDataIO provides, remaining blissfully ignorant of Windows' limitations regarding stdin. Have a look here and here if you like, the code is all open-source/BSD-licensed.

我做了一些类似于jwhitlock的事情……最后,我得到了一个StdinDataIO类,它围绕合适的特定于操作系统的实现(*)进行包装,这样我的程序的其余部分就可以在StdinDataIO提供的文件描述符上选择(),仍然幸运地忽略了Windows对stdin的限制。如果你喜欢的话,可以看看这里和这里,这些代码都是开源的/ bsd许可的。

(*) the implementation is a simple pass-through for Linux/MacOSX, and in Windows it's a rather complex process of setting up a child thread to read from stdin and send the data it receives over a socket back to the main thread... not very elegant, but it works.

(*)实现是Linux/MacOSX的简单传递,在Windows中,设置子线程从stdin中读取数据并将其通过套接字接收的数据发送回主线程是一个相当复杂的过程……虽然不是很优雅,但很管用。

#1


6  

Maybe boost::asio can be of use for you?

也许boost::asio对你有帮助吗?

#2


1  

I used the threads and platform specific code. See my answer to another question. I was able to put the OS-specific stuff in inputAvailable() (Linux uses select, Windows just returns true). I could then use WaitForSingleObject() with a timeout on Windows to try to let the thread complete, then TerminateThread() to kill it. Very ugly, but the team didn't want to use this bit of boost.

我使用了特定于线程和平台的代码。请看我对另一个问题的回答。我能够将特定于操作系统的内容放入inputAvailable() (Linux使用select, Windows只返回true)中。然后,我可以使用WaitForSingleObject(),在Windows上设置一个超时,以尝试让线程完成,然后终止ethread()来终止它。很丑,但是球队不想用这种刺激。

#3


0  

I did something similar to jwhitlock ... I ended up with a StdinDataIO class that wraps around the appropriate OS-specific implementation(*) so that the rest of my program can select() on the file descriptor StdinDataIO provides, remaining blissfully ignorant of Windows' limitations regarding stdin. Have a look here and here if you like, the code is all open-source/BSD-licensed.

我做了一些类似于jwhitlock的事情……最后,我得到了一个StdinDataIO类,它围绕合适的特定于操作系统的实现(*)进行包装,这样我的程序的其余部分就可以在StdinDataIO提供的文件描述符上选择(),仍然幸运地忽略了Windows对stdin的限制。如果你喜欢的话,可以看看这里和这里,这些代码都是开源的/ bsd许可的。

(*) the implementation is a simple pass-through for Linux/MacOSX, and in Windows it's a rather complex process of setting up a child thread to read from stdin and send the data it receives over a socket back to the main thread... not very elegant, but it works.

(*)实现是Linux/MacOSX的简单传递,在Windows中,设置子线程从stdin中读取数据并将其通过套接字接收的数据发送回主线程是一个相当复杂的过程……虽然不是很优雅,但很管用。