0

qInstallMessageHandler用来注册自定义日志记录功能。此函数格式化消息(例如,它添加时间戳)并将其打印到控制台和日志文件。

我担心的是,如果 Qt 库组件(如QDateTime, QDir, QFile...)可以调用qDebug(),qWarning()等?

如果是,这可能会导致无限递归......

4

1 回答 1

1

简单的答案是:避免重新输入您的消息处理程序,然后:

// 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实例就是这样。

异步日志记录是通过在消息处理程序中发出信号来实现的,并通过显式排队连接处理从连接到信号的槽/函子的日志写入。您可能希望您的记录器驻留在自己的线程中,因此这是一种非常自然的方法并且效果很好。

于 2016-06-24T15:05:26.200 回答