Sign in to follow this  

std::cout syncronization in multithreading

This topic is 4857 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all, I'm writing a multithreaded text application in Win32, C++ and STLport, using std::cout for text output. The output stream is not automatically synchronized and I get messy outputs like: Thread1 code: cout << "Hello" << endl; Thread2 code: cout << "World!" << endl; Output: HeWlorlld!o There is a simply way to make it synchronized? Thanks.

Share this post


Link to post
Share on other sites
It's not exactly simple, in that it isn't transparent, but you could create a few simple little classes like so:


class c_Mutex
{
public:
c_Mutex();
~c_Mutex();
void Enter();
bool TryEnter();
void Leave();

protected:
CRITICAL_SECTION mCriticalSection;
};

class c_Mutex_Lock
{
public:
c_Mutex_Lock(c_Mutex* pMutex);
~c_Mutex_Lock();

protected:
c_Mutex* mpMutex;
};



c_Mutex::c_Mutex()
{
InitializeCriticalSection(&mCriticalSection);
}

c_Mutex::~c_Mutex()
{
DeleteCriticalSection(&mCriticalSection);
}

void c_Mutex::Enter()
{
EnterCriticalSection(&mCriticalSection);
}

bool c_Mutex::TryEnter()
{
return TryEnterCriticalSection(&mCriticalSection) != FALSE;
}

void c_Mutex::Leave()
{
LeaveCriticalSection(&mCriticalSection);
}



c_Mutex_Lock::c_Mutex_Lock(c_Mutex* pMutex)
{
mpMutex = pMutex;
if (mpMutex != NULL)
mpMutex->Enter();
}

c_Mutex_Lock::~c_Mutex_Lock()
{
if (mpMutex != NULL)
{
mpMutex->Leave();
}
}




Then you can create a global somewhere, call it something like gOutMutex. In your source code, when you want to print something out, put all the std::cout statements in an extra set of curly braces, and declare a c_Mutex_Lock object at th top:


c_Mutex gOutMutex;

int main()
{
//Start threads here...

{
c_Mutex_Lock OutLock(&gOutMutex);
std::cout << "Blah" << std::endl;
std::cout << "More Blah" << std::endl;
std::cout << "Final Blah" << std::endl;
}

return 0;
};



The c_Mutex_Lock object will lock the c_Mutex object on creation, and when it goes out of scope (at the end of the block), it will unlock the c_Mutex object. It is safe even against exceptions, since the c_Mutex_Object's destructor will be called then as well. It adds a few lines to every time you want to print stuff out, but it gets the job done.

Share this post


Link to post
Share on other sites
Quote:
Original post by Stoffel
Also, I believe cout is internally synchronized, so you can just make sure you write to a single formatted string first, then put that string out to cout in one call.
In my experience (with VC++'s implementation, using the multithreaded library) this is not the case. Somehow it manages to not only get characters from two different threads mixed together (even if each thread only uses a single << operator), but often seems to grab one character from each thread, alternating back and forth perfectly. Maybe other implementations handle this better...

Share this post


Link to post
Share on other sites
Thanks Agony, I like your solution. I was thinking something similar but you did it better :)

Oh, I forgot.. I'm using STLport with the _STLP_NO_OWN_IOSTREAMS option. This option disable the use of STLport iostreams and use wrappers around compiler's iostreams, in my case VC++. Maybe with STLport iostreams, cout is automatically synchronized.. I have to try..

Share this post


Link to post
Share on other sites

This topic is 4857 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this