|
|
 | | From: | SiamGod | | Subject: | cout and multiple threads | | Date: | 6 Jan 2005 12:22:19 -0800 |
|
|
 | I have an application on windows that uses multiple threads, but when ever I cout << "Write Something" << endl;
the I/O stops working. I created a SafeCout class that should work but does not.
class SafeCoutObj { public: stringstream Out;
SafeCoutObj & operator << (SafeCoutObj& (*pf)(SafeCoutObj&)) { return pf (*this)}
SafeCoutObj & endl() { lock(Mutex); printf("%s", Out.str().c_str()); Out.str()""); unlock(Mutex); return *this; } }
template inline SafeCoutObj& operator << (SafeCoutObj& os, Type val) { os.Out << val; return os; }
inline SafeCoutObj& endl(SafeCoutObj& os) { os.endl(); return os; }
Each thread has its own local copy of SafeCout it writes to.
When I run, everything starts out okay, but eventually, the endl function puts out the same line twice, and everything dies.
Any thoughts? Is this a Codewarrior cout limitation or multi-thread I/O problem?
Thanks
|
|
 | | From: | Howard Hinnant | | Subject: | Re: cout and multiple threads | | Date: | Thu, 06 Jan 2005 21:20:06 GMT |
|
|
 | In article <1105042939.679009.282610@c13g2000cwb.googlegroups.com>, "SiamGod" wrote:
> I have an application on windows that uses multiple threads, but when > ever I > cout << "Write Something" << endl; > > the I/O stops working. I created a SafeCout class that should work but > does not. > > class SafeCoutObj { > public: > stringstream Out; > > SafeCoutObj & operator << (SafeCoutObj& (*pf)(SafeCoutObj&)) > { return pf (*this)} > > SafeCoutObj & endl() > { > lock(Mutex); > printf("%s", Out.str().c_str()); > Out.str()""); > unlock(Mutex); > return *this; > } > } > > template > inline SafeCoutObj& operator << (SafeCoutObj& os, Type val) > { > os.Out << val; > return os; > } > > inline SafeCoutObj& endl(SafeCoutObj& os) > { > os.endl(); > return os; > } > > Each thread has its own local copy of SafeCout it writes to. > > When I run, everything starts out okay, but eventually, the endl > function puts out the same line twice, and everything dies. > > Any thoughts? Is this a Codewarrior cout limitation or multi-thread > I/O problem?
The usual way to handle multiple threads writing to the global cout is to create a global "cout_mutex" and lock it while using cout:
#include #include
Metrowerks::mutex cout_mut;
struct thread_main { thread_main(int id) : id_(id) {} int id_; void operator()(); };
void thread_main::operator()() { for (int i = 0; i < 100; ++i) { Metrowerks::mutex::scoped_lock lock(cout_mut); std::cout << "Running thread " << id_ << '\n'; } }
int main() { Metrowerks::thread t1(thread_main(1)); Metrowerks::thread t2(thread_main(2)); Metrowerks::thread t3(thread_main(3)); Metrowerks::thread t4(thread_main(4)); Metrowerks::thread t5(thread_main(5)); t1.join(); t2.join(); t3.join(); t4.join(); t5.join(); }
The Metrowerks::threads lib requires Pro 9. But the behavior of cout (requiring a mutex) is consistent for all Windows releases.
This behavior is consistent with our general policy: Non-const operations on an object from multiple threads is not allowed. But simultaneous const operations on an object is allowed.
Note that if we did lock cout internally, then it still would not run this program correctly without cout_mut: the "Running thread ", id_ and '\n' output would (likely) get scrambled. So the internal lock would be redundant and simply a performance and size waste.
-Howard
|
|
|