Я пишу регистратор и хотел бы сделать его потокобезопасным. Я сделал это, выполнив следующие действия:C++ 11 Нитевидный полиморфизм с меньшей детализацией
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) Caller этих публичной функции блокирует весь объект, используя семафор в классе
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;
};
Однако это решение очень ресурсоемкое, блокировка для каждого элемента.
У меня на правильном пути или есть что-то, что мне не хватает?
Почему вы не можете установить поток и степень серьезности в конструкторе? –
Конструктор назначит правильные значения по умолчанию (std :: cout, LogCritical), а общедоступные методы позволяют пользователю их изменять. Это решение для удобства использования, я боюсь, что его можно скомпоновать в конструктор, чтобы избавить эту проблему, не принесет мне никакой пользы. – cvicci
@cvicci, соглашайтесь с Крисом. Я думаю, вы должны пересмотреть свои варианты использования. Обычно вы можете устанавливать вещи во время строительства или аналогично в основном потоке, прежде чем появятся другие потоки. Тогда вам не нужен замок для этих сеттеров/геттеров. –