I am seeing bizarre (to me!) behaviours of ostreams using Sun's C++ 5.0
under Solaris 2.7 in a multithread environment. Any hints & tips would do
much for my sanity...
When I insert a simple type onto an ostream, the calling thread seems to
lock. I believe that it is deadlocked for some reason on the guard mutex for
the streambuf, but I'm still digging to get absolutely conclusive evidence
for that. This deadlock seems to happen when inserting an int or a double
onto the stream, but not a char*. I haven't done an exhaustive check on
other types. So
os << "Hi there"; // no problem
os << "Bye then " << 10; // displays "Bye then ", then locks thread
I have stripped away most irrelevent code to leave me the bare bones of a
program which still exhibits the behaviour. In essence, main creates a
thread bound to a LWP which then sets up a signal handler and uses
setitimer() to get ITIMER_REAL to wake up every second. When it wakes up, it
posts a semaphore that the main thread waits on. The main thread displays
shared state stuff to cout (suitably locking access to that shared state),
then returns to wait on the semaphore.
All of the ostream stuff is confined to the main thread, and the effect is
unchanged whether I use cout or an ostream object entirely local to that
main thread. I'm using C++ 5.0's default iostreams (which appear to come
from Rogue Wave) not the "classic" streams from 4.x.
I've read the dire warnings in Sun's documentation about the use of
ITIMER_REAL in an MT environment - However, I'm doing no masking, using a
bound thread and can accept that current per-thread behaviour will become
per-process in the future, so I think I'm OK there.
The signal handler itself is pretty straightforward - it just sem_posts an
event to a semaphore to wake up the timer thread. sem_post claims to be
async safe in attributes(5). I'm not doing any news or deletes using
iostreams or anything else that looks async unsafe in the handler.
When the main thread hangs, the timer thread carries on fine, waking up
every second posting its semaphore that main thread would wait upon were it
not deadlocked then waiting on its semaphore. If I add insertions onto cout
into the timer thread's context, then everything is fine until the main
thread hangs, when it too hangs. One second later the next signal is
uncaught and the process exits, as you'd expect.
Have you stumbled across anything similar???
ps: I'll see e-mail responses faster if they're to my work e-mail: