As notes by the OP, the /proc
file system has a 'stat' file for each process, /proc/PROCESS-ID/stat
and for each task /proc/PROCESS-ID/task/TASKID/stat
. The later is the process stat is aggregate of all tasks (including completed tasks!).
As per man proc
: fields 14, 15 in stat
file include CPU (user, kernel) used.
That leave with the task of mapping threads to TASKID. As noted in the man page (see quotes), there is no direct API to gettid, instead the syscall is needed
For interactive utility, consider top
(use y
for task mode)
For code that can be used inside an app, see below
#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 ;
}
The man page for gettid
states:
GETTID(2)
NAME
gettid - get thread identification
SYNOPSIS
#include
pid_t gettid(void);
Note: There is no glibc wrapper for this system call; see NOTES.
And later on:
NOTES
Glibc does not provide a wrapper for this system call; call it using 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)).
With the example code in 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);
...
}