4 ms·
This is a nice paradigm when it works, however for programs that are often piped to other programs, I believe this can run into issues with the flush on stdout
by gte910h 17y ago
This is a nice paradigm when it works, however for programs that are often piped to other programs, I believe this can run into issues with the flush on stdout blocking. Am I wrong here?
- Periodic 17y agoWon't it just get buffered into the other program's input buffer? I believe pipes are block-buffered and basically look just like redirecting to a file.
- jrockway 17y agoIf the process you're piping to never reads stdin and your process writes to stdout with a blocking write, you will eventually be blocked. But just use an event loop for stdout, and all will be well. (That way your program is in control of its own buffering and blocking. select is probably good enough in this case.) Anyway, if you want to see freakin' echo block because of this, try: $ mkfifo foo $ echo "OH HAI" > foo <blocks> In another xterm: $ cat foo <echo unblocks and exits>.
- btilly 17y agoThe potential problem comes when stdout and stderr are going to different places. For instance stdout is going to the next stage in a pipeline while stderr is going to the console. Then the error message winds up waiting for the buffering program.
- gte910h 17y agoYes exactly. This is the scenario I'm worried about. It's pretty common actually (think logging, etc)
- scott_s 17y agoI looked up the man page for C's fflush(). One of the error messages is EPIPE, "An attempt is made to write to a pipe or FIFO that is not open for reading by any process. A SIGPIPE signal shall also be sent to the thread." So, at least in C, I think flushing is intelligent enough not to block if no one's receiving the output.
- gte910h 17y agoI'm not talking about no one receiving output. I'm talking about this case: You write a program called "thefirstprogram". Who cares what it does. However, a user is pushing its (standard) output into a second program called "asecondprogram". Now imagine "asecondprogram" has melted, but not terminated. It's basically in a screwed up state. So the run command was: bash-2.04> thefirstprogram | asecondprogram I believe the flushing scheme advocated in the article is to be considered harmful, as you will in fact never see an error message if asecondprogram gets in a bad state and stops reading from stdin (and the buffers fill up). I do agree the flushing makes for nicer ordering of error messages, but is more fragile. Only used flushed output when you really need flushed output otherwise you'll get less resilience in the case of meltdown of cooperating programs.
- ars 17y agoWhat?! If the second program is messed up, it makes no difference if you flush or not. You'll still never see an error message. Stdin will fill up, flush or not, the program will block, and then sit there - no error message. You could maybe detect if stdin is blocked and say something on stderr - but if you want to do that it makes no difference whatsoever if you flush stdout or not.
- gte910h 17y agoNo, stderr isn't being piped with that command. So you will see it printed out on the command line. You have to explicitly pipe stderr as well if you don't want this behavior
- ars 17y agoYou don't understand. Once stdout blocks the whole program blocks, so it makes no difference that stderr is not piped. The program is stopped, it won't be making any errors. Obviously you could make some complicated buffering scheme - but you can do that and flush things anyway. The flush or no flush makes no difference.
- ars 17y agoIf that happens, it's supposed to block, so let it. So yes, you are wrong here.