我qInstallMessageHandler
用来注册自定义日志记录功能。此函数格式化消息(例如,它添加时间戳)并将其打印到控制台和日志文件。
我担心的是,如果 Qt 库组件(如QDateTime
, QDir
, QFile
...)可以调用qDebug()
,qWarning()
等?
如果是,这可能会导致无限递归......
简单的答案是:避免重新输入您的消息处理程序,然后:
// C++11, Qt 5.4+
void myMessageHandler(…) {
thread_local bool entered = false;
if (entered) return; // oops
QScopedValueRollback set{entered, true};
…
}
// C++11, Qt 4.8+
void myMessageHandler(…) {
thread_local bool entered = false;
if (entered) return; // oops
QScopedValueRollback back{entered};
entered = true;
…
}
// C++98, Qt 4
QThreadStorage<bool> entered;
void myMessageHandler(…) {
if (entered.localData()) return;
QScopedValueRollback back(entered.localData());
entered.localData() = true;
…
}
对于后代来说,这是一个古老而愚蠢的答案:
仅当您的日志记录是同步的时,它才会导致无限递归。一旦您使日志记录异步,您就不会再遇到问题了:消息处理程序将永远不会重新输入,因为您在发出信号后立即退出它,并且通过排队连接的信号发射发布零或相关线程的事件队列的更多QMetaCallEvent
实例就是这样。
异步日志记录是通过在消息处理程序中发出信号来实现的,并通过显式排队连接处理从连接到信号的槽/函子的日志写入。您可能希望您的记录器驻留在自己的线程中,因此这是一种非常自然的方法并且效果很好。