是否为记录器创建单独的线程?

Via*_*lov 9 c++ logging qt multithreading

我在Qt中编写了一个多线程应用程序(几个线程都有自己的事件循环).记录时,我希望记录器在日志中包含一个线程ID(它们具有有意义的名称).Qt默认记录器似乎无法做到这一点.所以我有三个选择:

  1. 每个线程都自己进行日志记录(这涉及互斥,因此可能是最糟糕的方法,但我不确定)
  2. 有一个专用的记录器线程和其他线程直接将事件发布到它(可能比3更快)
  3. 与2.相同但是消息是通过信号/插槽系统调度的(实际上,这也会导致发布事件).

哪一个更好,一般的最佳做法是什么?


在评论中提出问题后要澄清一些事项:

  • QThread有一个标准方法postEvent(),它是线程安全的.

所以问题就变成了,记录器线程是否需要为每个事件做足够的工作来证明在某种队列中编组事件数据的成本是合理的

  • 这就是问题的实质.我知道最好的答案是"测量!",但目前应用程序处于早期开发阶段,没有太多可衡量的.从一开始就选择合适的设计总是好的.
  • 在我的情况下,线程可能是一个好主意:它是一个媒体播放器,所以有GUI线程,回放线程,DB /媒体库线程,网络线程池......换句话说,整个动物园的线程.

Pet*_*ica 9

这些是一般性的评论,因为我没有Qt的经验.关于排队的成本,一般来说:I/O通常会让其他运行时成本变得苍白,所以无所谓.

专用日志记录线程的属性:

  • 好:对程序的运行时行为影响最小.
  • 好:保证单个日志消息(不是来自多个线程的混合输出).
  • 不好:重大的实施工作.
  • 错误:启动和实际执行日志记录的时间是分离的(这就是重点!).您可能会看到日志记录输出不在您期望的位置.
  • 错误:终止程序可能吞下最后和最重要的日志消息(Andreas的观点),因此您可能想要添加同步日志功能(这是上述要点的极端).

直接从每个线程记录的(dis)优点与上述相反.没有两个线程可以同时记录(因为函数像printf()隐式锁定a FILE,或者因为你明确地同步了日志函数); 这使得所有想要记录块的线程在当前线程完成之前.如果为了调试目的而进行了日志记录,则可能希望记录无缓冲(以便在发生后续崩溃时数据不会丢失),这会加剧运行时的影响.

这有多糟糕取决于应用程序的性质以及日志记录机制和数据量.