为日志记录重载 << 运算符的设计的潜在问题
Potential problems with a design that overloads << operator for logging
我想写一个 class 可以像 std::cout
使用 <<
运算符一样使用。我希望能够在使用一系列 <<
运算符的代码段的开头获得互斥锁,并在语句结束时释放该互斥锁。
例如:
logger << "Information blah "<< 1;
没有锁,在多线程操作中,事情可能会在 "Information blah " 和 1 之间交错。
这些 classes 的设计是否存在重大问题?我知道有大量的日志记录库,我只是在尝试一种在一系列 <<
运算符开始时维护互斥锁并在结束时释放互斥锁的方法。
class Logger;
class LockedLogger
{
public:
LockedLogger(Logger & logger):logger_(logger),lock_(new std::lock_guard<std::mutex>(logger.outputMutex_)) {};
template<typename T>
const LockedLogger & operator <<(T t) const{//Logging Code.}
private:
LockedLogger & logger_;
std::shared_ptr<std::lock_guard<std::mutex> > lock_;
};
class Logger
{
public:
Logger();
template<typename T>
LockedLogger operator << (T t){return LockedLogger(*this) << t;}
private:
std::mutex outputMutex_;
friend class LockedLogger;
};
Logger logger;
如果您选择使用锁定的记录器,那么当一个线程正在记录并可能准备要记录的内容时,您将停止其他线程 information/strings。
相反,你为什么不想办法在没有锁的情况下准备要记录的 information/string(例如,进入 function/scope 本地或线程本地 object/string)然后一次记录整个 information/string,保持同步部分尽可能短。
我想写一个 class 可以像 std::cout
使用 <<
运算符一样使用。我希望能够在使用一系列 <<
运算符的代码段的开头获得互斥锁,并在语句结束时释放该互斥锁。
例如:
logger << "Information blah "<< 1;
没有锁,在多线程操作中,事情可能会在 "Information blah " 和 1 之间交错。
这些 classes 的设计是否存在重大问题?我知道有大量的日志记录库,我只是在尝试一种在一系列 <<
运算符开始时维护互斥锁并在结束时释放互斥锁的方法。
class Logger;
class LockedLogger
{
public:
LockedLogger(Logger & logger):logger_(logger),lock_(new std::lock_guard<std::mutex>(logger.outputMutex_)) {};
template<typename T>
const LockedLogger & operator <<(T t) const{//Logging Code.}
private:
LockedLogger & logger_;
std::shared_ptr<std::lock_guard<std::mutex> > lock_;
};
class Logger
{
public:
Logger();
template<typename T>
LockedLogger operator << (T t){return LockedLogger(*this) << t;}
private:
std::mutex outputMutex_;
friend class LockedLogger;
};
Logger logger;
如果您选择使用锁定的记录器,那么当一个线程正在记录并可能准备要记录的内容时,您将停止其他线程 information/strings。
相反,你为什么不想办法在没有锁的情况下准备要记录的 information/string(例如,进入 function/scope 本地或线程本地 object/string)然后一次记录整个 information/string,保持同步部分尽可能短。