For Programmers: Free Programming Magazines  


Home > Archive > VC STL > February 2006 > help! anyone knows how to improve STL multi-thread synch?









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author help! anyone knows how to improve STL multi-thread synch?
Zhang, Xiaowei

2006-02-20, 3:57 am

Hi, all

I have met one puzzle about STL.

1. Redirect std::cout to one log file. *stdout = *logFilePointer;

2. Try to write to std::cout in 4 threads at the same time. Like,
std::cout<<"thread i:"<<timegettime()<<std::endl;

3. In general, in 10 minutes, application crashes on one Dell 4500 PC, JPN
XP SP2. but when I tested it on other computers on the same OS, it works
well.




If using the default cout to console, it is much more stable on all PCs.



is there any synch mechanism in STL in such case? what can I do to improve
it?



Thanks.

Zhang, Xiaowei


Tom Widmer [VC++ MVP]

2006-02-20, 7:57 am

Zhang, Xiaowei wrote:
> Hi, all
>
> I have met one puzzle about STL.
>
> 1. Redirect std::cout to one log file. *stdout = *logFilePointer;


That is not the correct way to redirect cout. Instead, try:

int main()
{
std::filebuf fb;
fb.open("logfile.txt", std::ios_base::out);
std::streambuf* oldcout = std::cout.rdbuf(&fb);
// rest of program

//must reset before exit:
std::cout.rdbuf(oldcout);
}

> 2. Try to write to std::cout in 4 threads at the same time. Like,
> std::cout<<"thread i:"<<timegettime()<<std::endl;


That can never be atomic, regardless of how cout is implemented. You are
making 3 calls to std::cout functions, and even if each of those is
atomic, you may get the output multiplexed:
"thread i:thread i:100

200
"
or similar.

>
> 3. In general, in 10 minutes, application crashes on one Dell 4500 PC, JPN
> XP SP2. but when I tested it on other computers on the same OS, it works
> well.


Or rather, happens to work. The code is not thread safe.

> If using the default cout to console, it is much more stable on all PCs.
>
>
>
> is there any synch mechanism in STL in such case? what can I do to improve
> it?


You need to protect all access to std::cout with a critical section.
Alternatively, you could use a threadsafe logging API. The simplest way
to fix your code is with something like this:

//cout.h
#include <iostream>
#include <boost/thread/mutex.hpp> //www.boost.org

extern boost::recursive_mutex cout_mutex; //define in a .cpp file
#define COUT (boost::scoped_lock(cout_mutex), std::cout)

Then you can do:

COUT<<"thread i:"<<timegettime()<<std::endl;

and it will be atomic. There are ways to do it without macros, but that
is the simplest I think.

Tom
Ulrich Eckhardt

2006-02-20, 7:57 am

Zhang, Xiaowei wrote:
> 1. Redirect std::cout to one log file. *stdout = *logFilePointer;


Wrong. If you want to redirect std::cout, plug in a different streambuffer
using the rdbuf() method.

> 2. Try to write to std::cout in 4 threads at the same time. Like,
> std::cout<<"thread i:"<<timegettime()<<std::endl;
>
> 3. In general, in 10 minutes, application crashes on one Dell 4500 PC, JPN
> XP SP2. but when I tested it on other computers on the same OS, it works
> well.
>
> If using the default cout to console, it is much more stable on all PCs.


The default simply forwards the calls to the underlying API to access the
console which seems to be threadsafe. The file-access however relies on not
two threads writing to it at the same time - it would be disastrous
normally to do so, so nobody bother to sync it.

> is there any synch mechanism in STL in such case? what can I do to improve
> it?


Create your own streambuffer that does proper locking.

BTW: the STL contains only containers, iterators and algorithms, not
IOStreams. The C++ standardlibrary mostly incorporated the STL but it is
not the STL. I assume you really meant the C++ standardlibrary and not the
STL.

Uli

Jason Winnebeck

2006-02-20, 7:02 pm

Tom Widmer [VC++ MVP] wrote:
> That is not the correct way to redirect cout. Instead, try:
>
> int main()
> {
> std::filebuf fb;
> fb.open("logfile.txt", std::ios_base::out);
> std::streambuf* oldcout = std::cout.rdbuf(&fb);
> // rest of program
>
> //must reset before exit:
> std::cout.rdbuf(oldcout);
> }


Sorry for the side-question, but why does one need to reset the old
rdbuf? Is it to prevent a memory leak?

Jason
Ulrich Eckhardt

2006-02-20, 7:02 pm

Jason Winnebeck wrote:

> Tom Widmer [VC++ MVP] wrote:
>
> Sorry for the side-question, but why does one need to reset the old
> rdbuf? Is it to prevent a memory leak?


No, the filebuf goes out of scope and you need to make sure std::cout is
still referring to it. AFAIK, you don't have to reset it to the initial
value though, although I'd consider that good practice - after all someone
might want to write a last SOS before sinking even after main() has
returned and that call should not go to /dev/null.

Uli

Jason Winnebeck

2006-02-21, 7:04 pm

OK, that makes sense. Although for the second comment might not be as
relevant because usually one is redirecting cout/cerr/clog because the
program is a "headless" program, so the default cout probably isn't
going anywhere useful at the time. In a Java program I use a similar
technique for System.out/in/err because the program is an embedded program.

But as I said the filebuf comment makes sense so thanks for pointing
that out to me.

Jason

Ulrich Eckhardt wrote:
> No, the filebuf goes out of scope and you need to make sure std::cout is
> still referring to it. AFAIK, you don't have to reset it to the initial
> value though, although I'd consider that good practice - after all someone
> might want to write a last SOS before sinking even after main() has
> returned and that call should not go to /dev/null.
>
> Uli
>

Zhang, Xiaowei

2006-02-22, 3:58 am


"Ulrich Eckhardt" <eckhardt@satorlaser.com> wrote in message
news:32poc3-8ov.ln1@satorlaser.homedns.org...
> BTW: the STL contains only containers, iterators and algorithms, not
> IOStreams. The C++ standardlibrary mostly incorporated the STL but it is
> not the STL. I assume you really meant the C++ standardlibrary and not the
> STL.
>
> Uli
>

oh, somehow I mixed them together. when reading The C++ Programming
Langugage I just thought they were the same one.
Thank you for your comment.

Xiaowei


Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com