Latelly I\'ve been working with multi-thread coding, after a while writing I realized that if I used std::cout in different boost::threads, the output would came without a l
I resolved it by coding up a thin wrapper that locks a mutex on starting writing to the stream and releases it, along with flushing the stream, once the write statement is completed.
Usage: replace std::cout by safe_cout.
Keep in mind it does not support fancy std::cout features like std::endl.
See the code below or grab it from here: https://github.com/dkorolev/felicity/blob/master/safe_ostream.h
#include
#include
#include
#include
struct safe_ostream {
struct guarded_impl {
guarded_impl() = delete;
guarded_impl(const guarded_impl&) = delete;
void operator=(const guarded_impl&) = delete;
guarded_impl(std::ostream& ostream, std::mutex& mutex) : ostream_(ostream), guard_(mutex) {
}
~guarded_impl() {
ostream_.flush();
}
template void write(const T& x) {
ostream_ << x;
}
std::ostream& ostream_;
std::lock_guard guard_;
};
struct impl {
impl() = delete;
void operator=(const impl&) = delete;
impl(std::ostream& ostream, std::mutex& mutex) : unique_impl_(new guarded_impl(ostream, mutex)) {
}
impl(const impl& rhs) {
assert(rhs.unique_impl_.get());
unique_impl_.swap(rhs.unique_impl_);
}
template impl& operator<<(const T& x) {
guarded_impl* p = unique_impl_.get();
assert(p);
p->write(x);
return *this;
}
mutable std::unique_ptr unique_impl_;
};
explicit safe_ostream(std::ostream& ostream) : ostream_(ostream) {
}
template impl operator<<(const T& x) {
return impl(ostream_, mutex_) << x;
}
std::ostream& ostream_;
std::mutex mutex_;
};
safe_ostream safe_cout(std::cout);
safe_ostream safe_cerr(std::cerr);