短版:写一个同步的包装器, wrap std::cout
,然后使用 synchronizedcout
来写。
长版:
#include <mutex>
template<typename T>
struct Synchronized {
explicit Synchronized(T& t_):t(t_) {}
template<typename Functor>
auto operator()( Functor&& f ) const->decltype(f(t)) {
std::lock_guard<std::mutex> guard(myMutex);
return f(t);
}
// I could implement these, but I'm lazy:
Synchronized& operator=(Synchronized const&) = delete;
Synchronized& operator=(Synchronized &&) = delete;
Synchronized(Synchronized const&) = delete;
Synchronized(Synchronized &&) = delete;
private:
mutable T& t;
mutable std::mutex myMutex;
};
// in "sync_cout.h"
extern Synchronized<std::ostream> sync_cout;
// in "sync_cout.cpp"
Synchronized<std::ostream> sync_cout(std::cout);
// In "logger.h"
// #include "sync_cout.h"
class Logger {
public:
void log(string& msg){
sync_cout( [&](std::ostream& os) {
os << "[" << tag << "] " << msg;
});
}
private:
string tag;
};
(从Herb偷来的。以上任何错误都是我自己的,不是 Herb 的。)
为了获得卓越的性能,上述链接还包括一个非阻塞异步包装器。