【问题标题】:Independent logging in multithreaded applications多线程应用程序中的独立日志记录
【发布时间】:2019-06-14 16:24:19
【问题描述】:

我目前正在调试一个多线程应用程序(Linux ia64、ARM 下的 pthread)。 valgrind、helgrind 和 gdb 是我目前使用的工具。

存在一些同步问题,供以后分析, 我想将线程执行记录到一个或多个文件中。

天真的实现会做一些 write/fprintf 这可能 (取决于 libc 实现)锁定一些内部互斥锁。 这反过来会影响程序的行为 (我称之为“意外锁定”) 因此是不可接受的。

在互联网上搜索只能得到逆解, 即如何同步线程resp。如何登录。 注意:第三方日志库倾向于保证多线程安全 但与上述相反。

所以我想出了在内存中不同步缓存日志条目, 以每个线程为基础,并在程序退出时将其刷新到文件中。

我想这对于许多开发人员来说是一个普遍的问题,并且 我想知道是否有更好的 方法。 有什么建议吗?

【问题讨论】:

  • 如何使用 thread_local 文件描述符进行日志记录。例如thread_local const int log = open(make_name(gettid()),...)
  • 是的,这就是我在程序退出时所做的。出于性能原因,写入延迟。
  • 这不是问题中写的,也不是我建议的。不是在内存中缓存,而是在线程启动时为每个线程打开一个日志文件,然后直接写入,而不对文件进行任何缓存。由于每个线程都有自己的文件,写入不会导致线程间同步。
  • 我不完全理解您所说的“意外锁定”是什么意思,当您有多个线程写入同一个文件时,您需要某种形式的同步(不仅仅是偶然)
  • 1.我缺少的是保证写入两个不同的流根本不会交互。谢谢你的开导。 2. 我试图表达我想知道什么时候存在隐式同步,它使程序在调试版本(带日志记录)中工作,并可能让它在发布版本中表现完全不同(不带日志记录)。跨度>

标签: c++ c linux multithreading logging


【解决方案1】:

现代多线程安全高性能记录器通常:

  • 为每个线程提供单独的日志记录缓冲区,以便线程将日志消息写入缓冲区(单生产者单消费者无等待缓冲区)时不涉及锁定。
  • 日志消息是二进制的,在发出日志消息的线程中不会发生snprintf 或任何其他格式。例如。日志消息是格式字符串和参数的副本(格式字符串可以是浅拷贝)。
  • 拥有一个单独的 I/O 线程,用于从其他线程读取二进制日志消息、格式化它们并写入日志文件。
  • I/O 线程对日志缓冲区进行定期轮询,因此在发出日志消息时不需要跨线程消息传递。消息生产者可以选择通知 I/O 线程立即开始将日志消息写入日志文件(例如,日志缓冲区可用空间越来越少)。

【讨论】:

  • 但是消息传递会导致线程间同步,他想避免这种情况。
  • @Oliv 不一定。您可以使用轮询。
  • logger线程可以有无锁、无等待同步、多生产者单消费者队列?
  • 你有论文的链接或这样一个队列的源代码吗,我正在研究无锁结构,我真的很感兴趣。
  • @Oliv 我没有给你的公共资源。这有点乏味,但实施起来并不难。
猜你喜欢
  • 2011-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-11
  • 1970-01-01
  • 2020-07-11
  • 1970-01-01
  • 2014-02-15
相关资源
最近更新 更多