From: Joel VanderWerf Date: 2009-07-14T03:24:54+09:00 Subject: Re: Process.fork weirdness Joel VanderWerf wrote: > Gary Wright wrote: >> You need to flush the output stream before forking so that the child >> process doesn't get any buffered data. Otherwise, every time the child >> process exits, it will flush the duplicate data out to the >> 'output.txt' file. > > Huh, I never knew that. That's dangerous if the parent process is > multithreaded, isn't it? Because even if the forking thread flushes all > open files, other threads can keep filling buffers before the fork happens. > > In process.c, rb_f_fork() flushes stdout and stderr before forking, so > at least these two buffers are protected from other ruby threads. It > seems like there should be an option to flush everything. Maybe the best policy is to do any one of the following: 1. Avoid buffered output (puts, write), and instead use unbuffered calls (syswrite, send) or set io.sync=true. 2. Don't mix threads and fork, and flush everything before forking. 3. Create children only as fork {do_stuff; exit!} fork {do_stuff; exec ...} system "..." and so on. (And be careful that the do_stuff doesn't flush any buffered IO that belongs to the parent.) Most libraries aren't going to follow #1, and #2 seems impractical to enforce. Actually, I guess #3 is why I haven't seen this problem before... it's often a good idea to use exit! in fork to avoid duplicating at_exit() handlers anyway. I wish there were a method that the child could call before anything else to _clear_ (not flush) all buffers and also to clear the at_exit handlers. -- vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407