【发布时间】:2020-12-29 14:38:22
【问题描述】:
我在这里实现了一个 Logging 类。
class Log : public std::streambuf, public std::ostream {
public:
Log(int severity, const char* func, int line) :
std::ostream(this), severity_(severity) {
(this->severity_ == ERROR) ? std::cout << RED << "ERROR " :
std::cout << RESET << "INFO ";
std::cout << func << " @ line# " << line << ": ";
}
int overflow(int c) {
if (this->severity_ == ERROR) {
std::cout << RED;
std::cout.put((char) c);
} else {
std::cout.put((char) c);
}
return 0;
}
~Log() {
std::cout << RESET << std::endl;
}
private:
int severity_;
};
这很好用。但是当两个线程同时执行时,输出有时会混合在一起。我经历了几个 SO 问题,但他们都以更广泛的方式讨论了这个问题。我有这个我想修复的特定实现。我尝试添加一个全局互斥锁并以线程安全的方式调用它,但问题是该文件是一个全局头文件,因此不能在此处全局定义互斥锁变量,因为它会导致多个定义错误。有没有办法解决这个问题?
【问题讨论】:
-
全局变量最终会帮助你。最好是static member variable,这样所有记录器都共享一个记录器范围的互斥锁。
-
旁注:要解决全局互斥锁(可能只是众多互斥锁中的第一个)问题,请阅读How do I use extern to share variables between source files?
-
如果您在多个线程中使用一个
Log对象,则使用该对象的代码将负责同步对该对象的访问(创建一个互斥体,在使用Log之前获取它,释放完成后等)。如果你想要多个Log对象都写入一个公共流,Log类需要设置单个互斥体(例如作为类的静态成员),并且所有成员函数都需要在写入之前抓取互斥体到流,并在完成对流的操作后释放互斥锁。流本身可能也需要是静态类成员。
标签: c++ multithreading logging