Thomas Chust wrote at 02/06/2011 10:14 AM:
2011/2/6 Manfred Lotz <manfred.l...@arcor.de>:
[...]
I don't know how to merge stdout and stderr in proper sequence.
[...]

There is no such thing as proper sequencing of data flowing through different 
streams.

Due to buffering in system libraries and the operating system kernel it is also 
entirely impossible to reliably process the output data in the exact sequence 
it was produced by the external process.

Agreed with Thomas that doing this perfectly is impossible in the general case, even when there's a single-threaded producer of the two streams.

However, if you want to sequence reading stdout and stderr close enough for most purposes, keep in mind that these are usually interleaved at the resolution of lines rather than characters, so you can get this pretty much right, and still do fairly efficient block reads. So, you can do the sequencing efficiently in your reading process by doing raw stdio and avoiding any buffering port abstractions in your library, doing a "sync" loop on the ports, and implementing your own buffering for each port, out of which buffer you pick a complete line at a time. You also can tweak this to better interleave reads from the two streams/buffers. You can also use time or other heuristics to detect when, say, a stdout message like "Processing..." without newline should be handled because it was interrupted by a subsequent stderr error message. There might still be buffering outside of your control, but I think it doesn't often matter.

Once you get into "expect"-like interaction with a process using the three streams at once, and doing pattern-matching while also capturing the output, and doing this all efficiently, it's tricky. There's no reason that a generalized library routine to do this can't be implemented in Racket, but I'm not aware of one. If you hand-implement for a particular purpose, I think you'll be getting your hands dirty with "sync", your own buffering of both input and output, block I/O, and some strategy for how to do your pattern-matching efficiently on the buffers. IMHO, this should feel like systems programming if you're doing it efficiently. This complication does not reflect a limitation of Racket, but instead that Racket is flexible enough that this doing this complicated stuff is possible.

--
http://www.neilvandyke.org/

_________________________________________________
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/users

Reply via email to