http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56016
Bug #: 56016 Summary: mutlithreading problem with iostream Classification: Unclassified Product: gcc Version: 4.6.3 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: b...@justexpired.e4ward.com Created attachment 29188 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=29188 sample program I wrote a program that uses 2 threads (pthreads), one to read from stdin, the other to write to stdout. The goal is that even if stdout is blocked by a pipe, reading from stdin should not be blocked, instead, data should be accumulated in the program's heap and eventually copied to stdout. The program works fine if reading and writing are done with unistd (read/write) or cstdlib (fread/fwrite) routines, but not with iostream (cin.read/cout.write). I'm using stock Linux Mint 13, which comes with gcc 4.6.3. The program is attached, I compiled it with: $ g++ -g -o drain drain.cpp -lpthread To reproduce the bug, follow these steps: 1. Create an input file: $ dd if=/dev/zero bs=1024 count=256 >zeros 2. Create 2 named pipes: $ mkfifo pipe-1 $ mkfifo pipe-2 3. Start a source and a sink: $ cat zeros >pipe-1 & $ { sleep 3000000; cat >result; } <pipe-2 & 4. Finally, connect them with our program: $ ./drain 2 <pipe-1 >pipe-2 & Expected behaviour: job 1 (cat into pipe-1) should finish right away, with all input transferred to the buffers of ./drain. The output thread of ./drain should be blocked, waiting for somebody to read data from pipe-2. To cause the entire pipeline to complete, kill the sleep process with e.g. $ killall sleep This causes the cat in the sink to pull data from pipe-2. The expected behaviour occurs when using ./drain 0 (unistd routines) or ./drain 1 (cstdlib routines), but not with ./drain 2 (iostream routines) Observed behaviour: (most of the time...) job 1 doesn't complete. Instead, the input thread of ./drain blocks at some point, without completing the stdin reading. When the sleep process is killed, the entire pipeline completes. The problem is the blocking, though. Perhaps the blocked cout.write() holds some mutex, preventing cin.read() from completing. But I'm speculating here. Note: the named pipes have a certain capacity, in my case about 65536. This means the output thread of ./drain will be able to write a few blocks even before the sleep process ends and cat reads from pipe-2. For the same reason, the cat into pipe-1 might complete even if the input thread of ./drain blocks (which is the bad behaviour), as long as the difference can be held by pipe-1. The numbers make the bug reproducible on my system, but if the pipes have larger capacity, the size of the input should be increased.