Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Is iostream/fstream thread safe ?

648 views
Skip to first unread message

Yaakov Berkovitch

unread,
Jun 28, 2004, 11:33:51 AM6/28/04
to
Hi,
 
I'm running on Solaris 9 using C++ compiler SunOne Studio 8.
 
Our application crashed and the core show the following stack:
[1] t_splay(0x1244a30, 0x1244a30, 0xddca8f, 0xfc39a2d0, 0x0, 0x83b6ac), at 0xfc347834
[2] t_delete(0x1244a30, 0x40, 0x200, 0x16c8b88, 0x1244a30, 0x83b6ac), at 0xfc347698
[3] realfree(0x1244830, 0x744f8, 0x83e14c, 0xfc3bc000, 0xffffffe0, 0x4), at 0xfc3472b8
[4] cleanfree(0x0, 0x5, 0x21d54, 0xfc3bc000, 0x0, 0x8), at 0xfc347b58
[5] _malloc_unlocked(0x18, 0x0, 0x83e080, 0xfc3bc000, 0x83b6ac, 0xc), at 0xfc346ca4
[6] malloc(0x18, 0xfee5ef92, 0x8a3cc0, 0x0, 0x1, 0xf7174f94), at 0xfc346b74
[7] operator new(0x18, 0xf7175980, 0xd36ec, 0xfe0eb394, 0x0, 0x83b6ac), at 0x767fec
[8] stream_rmutex::rmutex_init(0xf7174e20, 0xff000000, 0x21d30, 0x18, 0x16d7b40, 0xf71735fc), at 0x760f60
[9] streambuf::streambuf(0xf7174e1c, 0x36c, 0xda3a4, 0xfc39a2d0, 0x0, 0x83b6ac), at 0x761334
[10] strstreambuf::strstreambuf(0xf7174e1c, 0x394, 0xd93d0, 0xfc346b80, 0x0, 0x83b6ac), at 0x762304
[11] unsafe_strstreambase::unsafe_strstreambase(0xf7174e18, 0x83e148, 0x83e14c, 0xfffffff8, 0xffffffe0, 0x4), at 0x7636ec
[12] strstreambase::strstreambase(0xf7174e14, 0x83e0a0, 0x83e0a8, 0x0, 0x83b6ac, 0x8), at 0x763a18
[13] ostrstream::ostrstream(0xf7174e14, 0x83e01c, 0x83e080, 0x0, 0x83b6ac, 0xc), at 0x76496c
=>[14] LoggerRecordStream::LoggerRecordStream(this = 0xf7174e14, severityLevel = 0xfee5ef92 "INFORMATION", logger = 0x8a3cc0), line 256 in "Logger.cc"
[15] CorOpticalInterfaceSonet::rimIfProvisionDataHandler(0x122c2a0, 0xf7175980, 0x87e400, 0x882f50, 0x882c00, 0xb2692c), at 0xfe0eb394
[16] CorOpticalInterfaceSonet::provisionEquipment(0x122c2a0, 0x0, 0x0, 0x1, 0x0, 0xf71763d0), at 0xfe0e9d54
[17] CorInterfaceSonetLine::sonetLineProvisionDataHandler(0x122c2f8, 0xf7176f28, 0x87e400, 0x882f50, 0x882c00, 0xb2692c), at 0xfe2e51c4
[18] CorInterfaceSonetLine::provisionEquipment(0x122c2f8, 0x1, 0x0, 0x1, 0x882c00, 0xd2b7a4), at 0xfe2e36e8
[19] CorInterfaceEntity::provisionEquipment(0x122c250, 0x1, 0x1, 0x0, 0x10, 0x20), at 0xfe05de04
[20] CorModule::provisionEquipment(0x11cf198, 0x1, 0x1, 0x1, 0x10, 0x20), at 0xfe6f4f6c
[21] CorSlot::matchPrePlanWithCA(0xd105b0, 0x1, 0x1f, 0x1, 0xffffffff, 0x0), at 0xfeb44764
[22] CorSlot::provisionEquipment(0xd105b0, 0xfafb1424, 0x0, 0x0, 0x0, 0x0), at 0xfeb3fe08
[23] ORVThreadFunctionM0<CorSlot>::functor(0x16b0690, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xfeb60d2c

 
Also another thread was using iostream call in the same time.
 
Do I need to protect access to the iostream library ?
 
Any tips are welcome - I'm really worried about this behaviour.
 
Thanks.
 
Yaakov Berkovitch
 

Paul Floyd

unread,
Jun 28, 2004, 3:37:14 PM6/28/04
to
On Mon, 28 Jun 2004 17:33:51 +0200, Yaakov Berkovitch
<jaa...@corrigent.com> wrote:
> This is a multi-part message in MIME format.

Please don't post MIME. You might be better off posting to a C++
Standard Library group.

> Hi,
>
> I'm running on Solaris 9 using C++ compiler SunOne Studio 8.
>

> [8] stream_rmutex::rmutex_init(0xf7174e20, 0xff000000, 0x21d30, 0x18, =
> 0x16d7b40, 0xf71735fc), at 0x760f60

Well that looks like a mutex.

> [13] ostrstream::ostrstream(0xf7174e14, 0x83e01c, 0x83e080, 0x0, =
> 0x83b6ac, 0xc), at 0x76496c

From man basic_ostream (which ostrstream inherits from):

They
both begin by constructing an object of class
basic_ostream::sentry and, if this object is in good state
after construction, the function tries to perform the
requested output. The sentry object performs exception-safe
initialization, such as controlling the status of the stream
or locking it in a multithread environment.

So it looks to me as though it should be thread safe if compiled with
-mt.

A bientot
Paul
--
Paul Floyd http://paulf.free.fr (for what it's worth)
Surgery: ennobled Gerald.

Seongbae Park

unread,
Jun 28, 2004, 5:57:51 PM6/28/04
to
Yaakov Berkovitch <jaa...@corrigent.com> wrote:
> This is a multi-part message in MIME format.
>
> ------=_NextPart_000_000D_01C45D36.13B76620
> Content-Type: text/plain;
> charset="windows-1255"
> Content-Transfer-Encoding: quoted-printable

>
> Hi,
>
> I'm running on Solaris 9 using C++ compiler SunOne Studio 8.
>
> Our application crashed and the core show the following stack:

...stack trace snipped...

> Also another thread was using iostream call in the same time.
>
> Do I need to protect access to the iostream library ?

No. But you need to compile and link your application with -mt option.
See Chapter 11 Building Multithreaded Programs in S1S8 C++ user's guide
(http://docs.sun.com/source/817-0926/Multithread.html).

Relavant part:

11.1 Building Multithreaded Programs

All libraries shipped with the C++ compiler are multithreading-safe.
If you want to build a multithreaded application, or if you want to
link your application to a multithreaded library, you must compile and
link your program with the -mt option. This option passes -D_REENTRANT
to the preprocessor and passes -lthread in the correct order to ld.
For compatibility mode (-compat[=4]), the -mt option ensures that
libthread is linked before libC. For standard mode (the default mode),
the -mt option ensures that libthread is linked before libCrun.

Do not link your application directly with -lthread because this
causes libthread to be linked in an incorrect order.

The following example shows the correct way to build a multithreaded
application when the compilation and linking are done in separate
steps:

example% CC -c -mt myprog.cc

example% CC -mt myprog.o


The following example shows the wrong way to build a multithreaded
application:

example% CC -c -mt myprog.o

example% CC myprog.o -lthread <- libthread is linked incorrectly

> Any tips are welcome - I'm really worried about this behaviour.
>
> Thanks.
>
> Yaakov Berkovitch
> jaa...@corrigent.com

All C++ standard libraries are thread safe, but not async safe.
Again, from C++ user guide:

11.1.2 Using C++ Support Libraries With Threads and Signals

The C++ support libraries, libCrun, libiostream, libCstd, and libC are
^^^
multithread safe but are not async safe. This means that in a
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
multithreaded application, functions available in the support
libraries should not be used in signal handlers. Doing so can result
in a deadlock situation.

It is not safe to use the following in a signal handler in a
multithreaded application:

* Iostreams

* new and delete expressions

* Exceptions

Seongbae

Yaakov Berkovitch

unread,
Jun 29, 2004, 5:10:42 AM6/29/04
to
Thanks for you professional answer.

The multi-threaded programs user's guide is really interessting.
BTW we are compiling with the -mt option, so it seems that our application
is
running is a safe mode regarding usage of iostream.

But the user's guide relates in the paragrah 11.4.4. the following:
".....To perform a sequence of operations on an iostream class object
atomically, you must use some form of locking. "

Is it says that if we are not locknig the iostream class object,
unpredictable result can occured even crash ?

Thanks.

"Seongbae Park" <Seongb...@Sun.COM> wrote in message
news:cbq48v$s52$1...@news1nwk.SFbay.Sun.COM...

Casper H.S. Dik

unread,
Jun 29, 2004, 4:35:40 AM6/29/04
to
"Yaakov Berkovitch" <jaa...@corrigent.com> writes:

>Thanks for you professional answer.

>The multi-threaded programs user's guide is really interessting.
>BTW we are compiling with the -mt option, so it seems that our application
>is
>running is a safe mode regarding usage of iostream.

>But the user's guide relates in the paragrah 11.4.4. the following:
>".....To perform a sequence of operations on an iostream class object
>atomically, you must use some form of locking. "

>Is it says that if we are not locknig the iostream class object,
>unpredictable result can occured even crash ?

No; what this means that if you want to *atomically* generate
output you need to use locking.

The output from all threads is interleaved with the granularity of
a single iostream operation; now that's not pretty if you print
lines consisting of several parts.

If you want to logically group the output you need to lock, start
output and the unlock.

Casper

Yaakov Berkovitch

unread,
Jun 29, 2004, 11:01:51 AM6/29/04
to
Great, your response is enough clear.

Thanks.

"Casper H.S. Dik" <Caspe...@Sun.COM> wrote in message
news:40e129dc$0$48920$e4fe...@news.xs4all.nl...

Seongbae Park

unread,
Jun 29, 2004, 1:31:29 PM6/29/04
to
"Casper H.S. Dik" <Caspe...@Sun.COM> wrote in message
> news:40e129dc$0$48920$e4fe...@news.xs4all.nl...
...

> >Is it says that if we are not locknig the iostream class object,
> >unpredictable result can occured even crash ?
>
> No; what this means that if you want to *atomically* generate
> output you need to use locking.
>
> The output from all threads is interleaved with the granularity of
> a single iostream operation; now that's not pretty if you print
> lines consisting of several parts.
>
> If you want to logically group the output you need to lock, start
> output and the unlock.
>
> Casper

There's one more reason to do locking beside pretty printing:
error handling and such.

11.4.1.3 shows a typical example -
istream::eof() or istream::fail() returns the state
of the istream which is the result of the *last* operation,
and in MT environment, another thread might have
done some operation between the operation and the error checking
in the current thread thus the last operation might not be
what you think it is, if they are not in a critical section.
This is essentially a very similar problem to output issue
Casper pointed out, just different aspect of iostream usage.

For more detail, please refer to Chapter 11 of C++ user guide.

Seongbae

0 new messages