跟踪线程的内存和CPU消耗

8
我正在编写一个Linux应用程序,该程序观察其他应用程序并跟踪资源的消耗。我计划使用Java进行开发,但对于我来说,编程语言并不重要。目标很重要,因此我可以切换到另一种技术或使用模块。我的应用程序将任何选择的第三方应用程序作为子进程运行。大多数子软件解决一些算法问题,例如图形、字符串搜索等。观察程序在子进程完成任务时跟踪其资源。
如果子应用程序是多线程的,可能可以以某种方式跟踪每个线程消耗的资源量?应用程序可以使用任何非分布式内存线程技术编写:Java线程、Boost线程、POSIX线程、OpenMP或其他任何线程技术。

1
你有没有看过 OProfile 以获取灵感?http://oprofile.sourceforge.net - Vinko Vrsalovic
不,这是我的硕士论文工作。也许我的讲师看过 :-) 但 OProfile 看起来很有趣。谢谢。 - Pawka
3个回答

6

在现代 Linux 系统(2.6版本)中,每个线程都有一个单独的标识符,几乎与 pid 的处理方式相同。它显示在进程表中(至少在 htop 程序中),并且它还有自己单独的 /proc 条目,即 /proc/<tid>/stat

请查看 man 5 proc,特别注意 statstatmstatus 等内容。您应该可以在其中找到您感兴趣的信息。

唯一的障碍是获取此线程标识符。它与进程ID不同! 即在所有线程中调用 getpid() 函数将返回相同的值。要获取实际的线程标识符,您应该使用以下代码(在 C 程序中):

pid_t tid = syscall(SYS_gettid);

顺便说一下,Java虚拟机(至少,其OpenJDK Linux实现)在内部执行此操作,并在其后端用于调试目的,但不将其公开给Java接口。

6

线程不分配内存,通常在线程之间共享内存。这使得谈论线程的内存消耗通常是不可能的,至少是没有意义的。

一个例子就是一个有11个线程的程序;其中1个线程创建对象,另外10个线程使用这些对象。大部分工作都在这10个线程中完成,但所有内存都是在创建对象的那个线程上分配的。现在如何解决这个问题呢?


我不能说你是错的。但我们可以假设单线程内存使用量是特定线程在当前时间工作时使用的内存量。大多数线程在处理数据时会使用信号量或互斥锁来锁定内存。 - Pawka
1
抱歉,但那仍然没有意义。只读存储器根本不需要锁定。当使用互斥量时,没有合理的方法可以确定它保护哪个内存,除非查看代码。 - MSalters
我不是在谈论只读内存。我们仍然可以计算线程的内存消耗。例如,使用某些图形工作,为某些计数创建节点等。每个这样的数据都可以由一个线程访问,由它自己创建并在工作完成后清除。 - Pawka
那么,当线程正在处理一个节点时,节点是否计入所使用的内存?或者整个图的内存是否计算在线程使用的内存中?我并不是说没有线程特定的分配。这简单地是不够的。在许多实际的程序中,你可能会发现,分配给进程的所有内存中有90%不能唯一地归属于任何一个线程。最终结果:进程使用50 MB,其10个线程中每个线程“使用”1 MB,而40 MB则“丢失”。因此,由于这种情况,您的结果将无法受到信任。 - MSalters

1
如果你想使用Perl,请看一下这个:Sys-Statistics-Linux 我将它与一些GD图形包一起使用,为各种进程生成系统资源使用图。
需要注意的一件事是 - 你真的需要阅读/proc并了解jiffies - 上次我查看时它们在man页面上没有正确记录,你可能需要阅读内核源代码。

http://lxr.linux.no/#linux+v2.6.18/include/linux/jiffies.h

此外,记住在Linux中线程和进程之间唯一的区别是线程共享内存 - 除此之外,它们在内核实现方式上完全相同。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接