记录线程事件

时间:2012-04-22 12:10:29

标签: linux gcc profiling pthreads

假设我需要定期查看线程的状态,并在整个程序执行过程中记录其状态。我不知道如何开始考虑这个问题。任何指针(双关语?)?我在Linux上,使用gccphreadsC并可以访问所有常用的Linux工具。基本上,我想我正在询问如何为线程构建一个简单的探查器,它将告诉我一个线程在执行程序期间处于某种状态或其他状态的时间。

我希望能够创建像Threadscope那样的图形。 X轴是时间,Y轴是核心/线程编号,“颜色”是状态:绿色表示运行,橙色表示垃圾收集,依此类推。这现在更有意义了吗?

Threadscope image

4 个答案:

答案 0 :(得分:4)

对于Linux特定的解决方案,您可能希望分别查看/proc/<pid>/stat/proc/<pid>/task/<tid>/stat的进程和线程统计信息。请查看proc(5)手册页,了解其中所有字段的完整说明(在线http://man7.org/linux/man-pages/man5/proc.5.html - 搜索/proc/[pid]/stat)。具体而言,至少字段cutimestime是您感兴趣的。这些是单调增加的时间,因此您需要记住先前测量的值,以便能够在给定时间片期间产生在进程/线程中花费的时间,以便为您的图形生成数据。 (这就是top(1)的工作方式。)

但是,对于剖析器来区分不同的状态会使问题更加复杂。探查器如何区分异形程序处于哪种状态?在我看来,配置文件程序线程需要以某种方式向分析器发出信号。你需要为这种状态共享提供某种定制的解决方案(除非你可以在不同的线程中运行不同的状态并以这种方式区分,我怀疑)。

如果状态转换是在一个地方完成的(例如输入GC 并且在示例中保留GC ),那么一种方法如下:

  1. 通过使用POSIX函数clock_gettime(),受监控的线程将获得特殊状态的开始和结束时间 - 使用clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp)可以获得处理时间,使用clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)可以获得线程时间(再次单调增加)。
  2. 线程可以使用某种IPC将这些时序传递给探查器程序。
  3. 如果探查器应用程序知道进入和离开状态的线程时间,那么因为它知道测量切片更改时的线程时间值,它可以确定在报告的状态中花费了多少线程时间。报告时间片(当然,我们需要将状态的开始时间调整为等于下一个报告时间片的开始)。
  4. 整个过程花在特定状态上的时间可以通过总结该状态的线程时间来计算。
  5. 请注意,通过/proc/<pid>/stat/proc/<pid>/task/<tid>/stat,测量精度不是很好(时钟滴答,通常是10ms的单位),但我不知道从外部获取时序信息的其他方式进程/线程。函数clock_gettime()给出非常准确的时间(名义上为纳秒精度,但请注意,至少在某些MIPS和ARM系统中,准确度与stat/proc文件一样糟糕在Linux内核中为这些字段实现准确的定时器读取。您还需要进行一些实验以确保这两个定时源确实会产生相同的结果(通过读取相同线程中的两个值)。您当然可以在线程中使用这些/proc/.../stat文件,但除非您在州内花费大量时间,否则准确性不是很好。

答案 1 :(得分:1)

嗯,直接匹配haskell编译器生成并由Threadscope处理的分析信息,使用C和GCC, gprof 实用程序(它是GNU binutils的一部分)。

为了使它与pthreads正常工作,你需要每个线程触发一些定时器初始化函数。这可以在不使用此pthreads包装器库修改代码的情况下完成:http://sam.zoy.org/writings/programming/gprof.html。我最近没有处理过这个问题,可能是因为某些东西已经改变了,不再需要包装了......

关于GUI来解释分析结果,有kprof(http://kprof.sourceforge.net)。不幸的是,AFAIK它不会生成线程持续时间图表,因此您必须使用gprof生成的文本信息来处理您自己的解决方案。

如果您对使用GCC提供的“标准”解决方案并不挑剔,您可以尝试这样做:http://code.google.com/p/gperftools/?redir=1(没有亲自尝试,但听到了很好的意见)。

祝你好运!

答案 2 :(得分:0)

查看Intel VTune Amplifier XE(以前称为......英特尔线程档案器),了解它是否符合您的需求。 这个和其他英特尔Linux开发工具可用free for non-commercial use

在显示多线程应用程序时间轴的视频Using the Timeline in Intel VTune Amplifier XE中,主持人在9:20提到 “...使用框架API,您可以编程方式标记代码中的某些事件或阶段。这些标记将显示在时间轴上。”

答案 3 :(得分:0)

我认为构建一个简单的分析器是相当困难的,因为你必须考虑许多不同的因素,系统分析是一项固有的复杂任务,当你是分析多线程应用程序。我能想到的最好建议是查看已存在的内容,例如OProfile

OProfile的一个优点是它是开源的source code is available。但除此之外,我怀疑询问如何构建分析应用程序可能超出了某个人在SO问题中可以回答的范围,这可能就是为什么这个问题没有得到很多答复。希望看一些例子可以帮助你开始,然后如果你有更集中的问题,你可以得到一些更详细的回答。