Re: Thread save access to cout?
On Feb 26, 6:09 am, Henryk <henryk.muel...@gmx.de> wrote:
is writing to cout thread save or do I
need to make it thread safe by some kind of wrapper?
Here is a simple solution, although it may require a lot of work to
install into your source code because it requires putting a ) at the
end of each print segement:
#define COUT_LOCK(x) {std::stringstream cout;\
x\
Lock lock(mutex);\
std::cout << cout.str();}
int main()
{
COUT_LOCK(cout << "Hello" << " world" << endl;)
COUT_LOCK(
cout << "Starting:";
for(int i = 0; i<10; i++)
{
cout << i;
}
cout << "done." << endl;)
return 0;
}
If your threading library has a concept of a thread id, something like
this is a little more complex, but easier to install into existing
software (actual thread safety needs to be filled in):
#include <iostream>
#include <sstream>
#include <map>
bool mutex = false;
class Lock
{
public:
Lock(bool & mutex) :
mutex(mutex)
{
while(mutex)
{
// wait
}
mutex = true;
}
~Lock()
{
mutex = false;
}
private:
bool & mutex;
};
typedef unsigned long pthread_t;
pthread_t pthread_self()
{
return 1ul;
}
namespace Threaded
{
class Endl
{
};
Endl endl;
class Print
{
public:
Print & operator<<(Endl)
{
if(buffers.find(pthread_self()) == buffers.end())
{
buffers.insert(std::pair<pthread_t, std::stringstream
*>(pthread_self(), new std::stringstream));
}
buffers[pthread_self()]->flush();
Lock lock(mutex);
std::cout << buffers[pthread_self()]->str() << std::endl;
buffers[pthread_self()]->seekg(std::stringstream::beg);
buffers[pthread_self()]->seekp(std::stringstream::beg);
return *this;
}
template <class T>
Print & operator<<(T const & t)
{
if(buffers.find(pthread_self()) == buffers.end())
{
buffers.insert(std::pair<pthread_t, std::stringstream
*>(pthread_self(), new std::stringstream));
}
*buffers[pthread_self()] << t;
return *this;
}
private:
static std::map<pthread_t, std::stringstream* > buffers;
};
std::map<pthread_t, std::stringstream *> Print::buffers;
Print cout;
};
using Threaded::cout;
using Threaded::endl;
char getSpace()
{
cout << "In getSpace" << endl;
return ' ';
}
int main()
{
cout << "Hello" << getSpace() << "world." << endl;
cout << "Starting:";
for(int i = 0; i<10; i++)
{
cout << i;
}
cout << "done." << endl;
return 0;
}