我正在编写一个日志记录器,并希望使其支持多线程。我通过以下方式实现了这一点:
class Logger
{
public:
virtual ~Logger();
LogSeverity GetSeverity() const;
void SetSeverity(LogSeverity s);
protected:
std::mutex mutex;
private:
LogSeverity severity;
};
void Logger::SetSeverity(LogSeverity s)
{
std::lock_guard<std::mutex> lock(mutex);
severity = s;
}
LogSeverity Logger::GetSeverity() const
{
std::lock_guard<std::mutex> lock(mutex);
return severity;
}
void Logger::SetSeverity(LogSeverity s) const
{
std::lock_guard<std::mutex> lock(mutex);
severity = s;
}
// StreamLogger inherits from Logger
void StreamLogger::SetStream(ostream* s)
{
std::lock_guard<std::mutex> lock(mutex);
stream = s;
}
ostream* StreamLogger::GetStream() const
{
std::lock_guard<std::mutex> lock(mutex);
return stream;
}
然而,所有公共访问该类的操作都需要这个非常冗余的锁。
我看到两个选项:
1)这些公共函数的调用者将使用类内的互斥锁锁定整个对象
Logger l = new Logger();
std::lock_guard<std::mutex> lock(l->lock());
l->SetSeverity(LogDebug);
2) 类中每个变量都有一个包装锁
template typename<T> struct synchronized
{
public:
synchronized=(const T &val);
// etc..
private:
std::mutex lock;
T v;
};
class Logger
{
private:
synchronized<LogSeverity> severity;
};
然而,这种解决方案非常资源密集,需要为每个项目锁定。
我是不是走在正确的道路上?还是我漏掉了什么?