我有一个在Linux上运行的基于C的应用程序,有大约30个线程。 现在我需要编写一个小实用程序,它在给定时间查找每个线程的CPU使用情况。它可以是应用程序的单独或部分。
/ proc的一个问题是找到哪个线程是什么。
请告诉我如何开始的一些想法。
由于
答案 0 :(得分:1)
我建议给每个线程一个易于理解的名称。该名称在线程级“ ps”输出(因此为“ ps -L PID”)中可见。
您使用以下(不可移植的)pthread api为每个线程命名:
int pthread_setname_np(pthread_t thread, const char *name);
多线程雷鸟的示例输出:
% ps -o pid,pcpu,comm,cmd -L 7111
PID %CPU COMMAND CMD
7111 8.3 thunderbird /usr/lib/thunderbird/thunderbird
7111 0.0 Gecko_IOThread /usr/lib/thunderbird/thunderbird
7111 0.0 Link Monitor /usr/lib/thunderbird/thunderbird
7111 0.0 Socket Thread /usr/lib/thunderbird/thunderbird
7111 0.0 JS Watchdog /usr/lib/thunderbird/thunderbird
7111 0.0 JS Helper /usr/lib/thunderbird/thunderbird
7111 0.1 JS Helper /usr/lib/thunderbird/thunderbird
7111 0.1 JS Helper /usr/lib/thunderbird/thunderbird
7111 0.1 JS Helper /usr/lib/thunderbird/thunderbird
7111 0.0 AudioIPC Callba /usr/lib/thunderbird/thunderbird
7111 0.0 AudioIPC Server /usr/lib/thunderbird/thunderbird
7111 0.0 BGReadURLs /usr/lib/thunderbird/thunderbird
7111 0.0 Hang Monitor /usr/lib/thunderbird/thunderbird
7111 0.0 gmain /usr/lib/thunderbird/thunderbird
7111 0.0 gdbus /usr/lib/thunderbird/thunderbird
7111 0.0 Cache2 I/O /usr/lib/thunderbird/thunderbird
7111 0.0 Cookie /usr/lib/thunderbird/thunderbird
7111 0.0 Timer /usr/lib/thunderbird/thunderbird
7111 0.0 GMPThread /usr/lib/thunderbird/thunderbird
7111 0.5 Softwar~cThread /usr/lib/thunderbird/thunderbird
7111 0.0 Compositor /usr/lib/thunderbird/thunderbird
7111 0.0 VRListener /usr/lib/thunderbird/thunderbird
7111 0.0 ImgDecoder #1 /usr/lib/thunderbird/thunderbird
7111 0.0 ImageIO /usr/lib/thunderbird/thunderbird
7111 0.0 IPDL Background /usr/lib/thunderbird/thunderbird
7111 0.0 HTML5 Parser /usr/lib/thunderbird/thunderbird
7111 0.0 LoadRoots /usr/lib/thunderbird/thunderbird
7111 0.0 DataStorage /usr/lib/thunderbird/thunderbird
7111 0.0 DataStorage /usr/lib/thunderbird/thunderbird
7111 0.0 mozStorage #1 /usr/lib/thunderbird/thunderbird
7111 0.0 StyleThread#0 /usr/lib/thunderbird/thunderbird
7111 0.0 StyleThread#1 /usr/lib/thunderbird/thunderbird
7111 0.0 StyleThread#2 /usr/lib/thunderbird/thunderbird
7111 0.0 ImgDecoder #2 /usr/lib/thunderbird/thunderbird
7111 0.0 dconf worker /usr/lib/thunderbird/thunderbird
7111 0.0 mozStorage #2 /usr/lib/thunderbird/thunderbird
7111 0.0 SysProxySetting /usr/lib/thunderbird/thunderbird
7111 0.0 ProxyResolution /usr/lib/thunderbird/thunderbird
7111 0.0 DataStorage /usr/lib/thunderbird/thunderbird
7111 0.0 URL Classifier /usr/lib/thunderbird/thunderbird
7111 0.0 Classif~ Update /usr/lib/thunderbird/thunderbird
7111 0.0 DNS Resolver #1 /usr/lib/thunderbird/thunderbird
7111 0.0 DOM Worker /usr/lib/thunderbird/thunderbird
7111 0.0 ImageBr~geChild /usr/lib/thunderbird/thunderbird
7111 0.0 mozStorage #3 /usr/lib/thunderbird/thunderbird
7111 0.0 thunderbird /usr/lib/thunderbird/thunderbird
7111 0.0 thunderbird /usr/lib/thunderbird/thunderbird
7111 0.0 thunderbird /usr/lib/thunderbird/thunderbird
7111 0.0 mozStorage #4 /usr/lib/thunderbird/thunderbird
7111 0.0 DNS Resolver #2 /usr/lib/thunderbird/thunderbird
7111 0.0 mozStorage #5 /usr/lib/thunderbird/thunderbird
7111 0.0 ImgDecoder #3 /usr/lib/thunderbird/thunderbird
7111 0.0 DNS Resolver #3 /usr/lib/thunderbird/thunderbird
7111 0.0 localStorage DB /usr/lib/thunderbird/thunderbird
7111 0.0 thunderbird /usr/lib/thunderbird/thunderbird
7111 0.0 thunderbird /usr/lib/thunderbird/thunderbird
7111 0.0 thunderbird /usr/lib/thunderbird/thunderbird
答案 1 :(得分:0)
虽然我在这个领域很天真,但我认为以下方法可能有效
1)维护一个更新的新PID列表,这些PID将在您的程序中在共享内存段中创建(我的想法是获取IPC的帮助)
2)开发一个应用程序,它能够访问先前创建的共享段并获取PID以检查相应的利用率。
答案 2 :(得分:0)
/ proc的问题之一是查找哪个线程是什么。
您可以使用pthread_setname_np设置线程名称来设置线程名称,并使用 / proc // task // status 或 / proc //检查给定时间的线程名称task // stat ,然后在stackoverflow上检查以下答案calculating-cpu-usage-for-given-pid以获得一些想法!
答案 3 :(得分:0)
如OP所述,/proc
文件系统为每个进程/proc/PROCESS-ID/stat
和每个任务/proc/PROCESS-ID/task/TASKID/stat
都有一个“ stat”文件。稍后是流程统计信息,它是所有任务(包括已完成的任务!)的汇总。
根据man proc
:stat
文件中的字段14、15包括使用的CPU(用户,内核)。
剩下的任务是将线程映射到TASKID。如手册页中所述(请参见引号),没有直接的API来获取gettid,而是需要syscall
对于交互式实用程序,请考虑使用top
(在任务模式下使用y
)
有关可在应用程序内部使用的代码,请参见下文
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>
pid_t get_task_id(void) ;
int get_task_cpu(pid_t tid) ;
int main(int argc, char *argv[])
{
pthread_create(...) ;
}
void thread_proc(void *arg) {
pid_t tid = get_task_id() ;
// do something
int cpu = get_task_cpu(tid) ;
printf("TID=%d CPU=%d\n", tid, cpu) ;
}
pid_t get_task_id(void) {
pid_t tid = syscall(SYS_gettid);
return tid ;
}
int get_task_cpu(pid_t tid) {
char fname[200] ;
snprintf(fname, sizeof(fname), "/proc/self/task/%d/stat", (int) get_task_id()) ;
FILE *fp = fopen(fname, "r") ;
if ( !fp ) return -1 ;
int ucpu = 0, scpu=0, tot_cpu = 0 ;
if ( fscanf(fp, "%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %d %d",
&ucpu, &scpu) == 2 )
tot_cpu = ucpu + scpu ;
fclose(fp) ;
return tot_cpu ;
}
gettid
的手册页指出:
GETTID(2)
NAME gettid-获取线程标识
简介 #include
pid_t gettid(void); Note: There is no glibc wrapper for this system call; see NOTES.
随后: 笔记 Glibc不为此系统调用提供包装器;使用syscall(2)调用它。
The thread ID returned by this call is not the same thing as a POSIX thread ID (i.e., the opaque value returned by pthread_self(3)).
在syscall中带有示例代码
#define _GNU_SOURCE #include <unistd.h> #include <sys/syscall.h> #include <sys/types.h> #include <signal.h> int main(int argc, char *argv[]) { pid_t tid; tid = syscall(SYS_gettid); ... }