In article <1105042939.679009.282610@[EMAIL PROTECTED]
>,
"SiamGod" <ed.woods@[EMAIL PROTECTED]
> 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 <class Type>
> 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 <msl_thread>
#include <iostream>
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


|