Linux proc/pid/task/tid/stat文件详解

本文详细解析了Linux系统中使用cat /proc/<pid>/stat获取的进程状态信息,包括PID、进程名、状态、父进程ID等关键字段的含义及用途。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[root@localhost ~]# cat /proc/6873/stat
6873 (a.out) R 6723 6873 6723 34819 6873 8388608 77 0 0 0 41958 31 0 0 25 0 3 0 5882654 1409024 56 4294967295 134512640 134513720 3215579040 0 2097798 0 0 0 0 0 0 0 17 0 0 0 [root@localhost ~]#


每个参数意思为:
参数                                                       解释
pid=6873                                              进程(包括轻量级进程,即线程)号
comm=a.out                                          应用程序或命令的名字
task_state=R                                        任务的状态,R:runnign, S:sleeping (TASK_INTERRUPTIBLE), D:disk sleep (TASK_UNINTERRUPTIBLE), T: stopped, T:tracing stop,Z:zombie, X:dead
ppid=6723                                            父进程ID
pgid=6873                                            线程组号
sid=6723                                              该任务所在的会话组ID
tty_nr=34819(pts/3)                            该任务的tty终端的设备号,INT(34817/256)=主设备号,(34817-主设备号)=次设备号
tty_pgrp=6873                                     终端的进程组号,当前运行在该任务所在终端的前台任务(包括shell 应用程序)的PID。
task->flags=8388608                           进程标志位,查看该任务的特性
min_flt=77                                            该任务不需要从硬盘拷数据而发生的缺页(次缺页)的次数
cmin_flt=0                                            累计的该任务的所有的waited-for进程曾经发生的次缺页的次数目
maj_flt=0                                              该任务需要从硬盘拷数据而发生的缺页(主缺页)的次数
cmaj_flt=0                                            累计的该任务的所有的waited-for进程曾经发生的主缺页的次数目
utime=1587                                          该任务在用户态运行的时间,单位为jiffies
stime=1                                                该任务在核心态运行的时间,单位为jiffies
cutime=0                                              累计的该任务的所有的waited-for进程曾经在用户态运行的时间,单位为jiffies
cstime=0                                              累计的该任务的所有的waited-for进程曾经在核心态运行的时间,单位为jiffies
priority=25                                           任务的动态优先级
nice=0                                                  任务的静态优先级
num_threads=3                                    该任务所在的线程组里线程的个数
it_real_value=0                                     由于计时间隔导致的下一个 SIGALRM 发送进程的时延,以 jiffy 为单位.
start_time=5882654                             该任务启动的时间,单位为jiffies
vsize=1409024(page)                       该任务的虚拟地址空间大小
rss=56(page)                                        该任务当前驻留物理地址空间的大小
Number of pages the process has in real memory,minu 3 for administrative purpose.
这些页可能用于代码,数据和栈。
rlim=4294967295(bytes)                  该任务能驻留物理地址空间的最大值
start_code=134512640                        该任务在虚拟地址空间的代码段的起始地址
end_code=134513720                         该任务在虚拟地址空间的代码段的结束地址
start_stack=3215579040                     该任务在虚拟地址空间的栈的结束地址
kstkesp=0                                            esp(32 位堆栈指针) 的当前值, 与在进程的内核堆栈页得到的一致.
kstkeip=2097798                                 指向将要执行的指令的指针, EIP(32 位指令指针)的当前值.
pendingsig=0                                       待处理信号的位图,记录发送给进程的普通信号
block_sig=0                                          阻塞信号的位图
sigign=0                                               忽略的信号的位图
sigcatch=082985                                  被俘获的信号的位图
wchan=0                                               如果该进程是睡眠状态,该值给出调度的调用点
nswap                                                   被swapped的页数,当前没用
cnswap                                                 所有子进程被swapped的页数的和,当前没用
exit_signal=17                                      该进程结束时,向父进程所发送的信号
task_cpu(task)=0                                  运行在哪个CPU上
task_rt_priority=0                                 实时进程的相对优先级别
task_policy=0                                        进程的调度策略,0=非实时进程,1=FIFO实时进程;2=RR实时进程

本文来自优快云博客,出处:http://blog.youkuaiyun.com/skydreamt/archive/2010/04/13/5480925.aspx

<think>好的,我现在需要帮助用户了解如何在NDK开发中实现访问stat64或/proc/pid/task/pid这样的系统信息。首先,我得确认用户的具体需求是什么。他们可能想获取某个进程或线程的详细信息,比如CPU使用情况或运行状态。 接下来,我应该回忆一下Linux系统中/proc文件系统的作用。/proc是一个虚拟文件系统,提供了进程和系统信息的接口。每个进程的目录下,比如/proc/pid,会有各种文件和子目录,其中task目录包含该进程的所有线程信息。statstatm这样的文件记录了进程的状态和内存使用情况。 然后,问题是如何在NDK(Native Development Kit)中访问这些信息。NDK允许Android应用使用C/C++代码,所以需要用系统调用来读取这些文件。但是需要注意权限问题,因为普通应用可能没有权限访问其他进程的/proc目录。用户可能需要他们的应用有足够的权限,或者只能访问自己的进程信息。 接下来,我需要考虑具体的实现步骤。首先,确定目标进程的PID,然后构建文件路径,比如/proc/[pid]/task/[tid]/stat。然后使用C标准库中的文件操作函数,如fopen、fgets等来读取文件内容。解析这些内容时,需要知道stat文件的格式,因为里面的数据是以空格分隔的数值,每个位置代表不同的信息,比如进程状态、CPU时间等。 此外,可能需要处理多线程的情况,遍历某个进程的所有线程,这可以通过读取/proc/pid/task目录下的子目录来实现,每个子目录对应一个线程的TID。然后对每个TID读取对应的stat文件。 还需要注意Android的权限限制。默认情况下,应用只能访问自己的进程信息,不能访问其他应用的,除非有root权限。所以用户的应用可能需要运行在root设备上,或者目标进程是同一个应用的。 另外,关于stat64系统调用,这可能涉及到获取文件状态的结构体,比如struct stat64,用于获取文件的大小、修改时间等信息。但用户的问题更可能是关于进程状态的stat文件,而不是文件系统的stat。 最后,需要提醒用户正确处理错误,比如文件不存在或权限不足的情况,以及确保NDK的配置正确,比如在Android.mk或CMakeLists.txt中启用必要的功能和库。 总结一下,步骤可能包括:获取PID,构建文件路径,读取文件内容,解析数据,处理多线程,处理权限问题。需要提供示例代码片段,展示如何打开和读取/proc文件,解析其中的字段,并注意权限和错误处理。</think>在NDK开发中访问`/proc/[pid]/task/[tid]/stat`或使用`stat64`获取进程/线程信息,需遵循以下步骤: --- ### 一、理解关键概念 1. **`/proc`文件系统** Linux虚拟文件系统,提供进程和系统信息。如`/proc/[pid]/task/[tid]/stat`记录线程状态。 2. **`stat64`系统调用** 用于获取文件状态(如大小、修改时间),需与`fstat64`配合读取文件元数据。 --- ### 二、实现步骤(以读取线程CPU时间为例) #### 1. 确定目标PIDTID - **当前进程PID**:通过`getpid()`获取 - **线程TID**:通过`gettid()`获取(需`<sys/syscall.h>`) #### 2. 构建文件路径 ```c++ char path[64]; snprintf(path, sizeof(path), "/proc/%d/task/%d/stat", pid, tid); ``` #### 3. 读取文件内容 ```c++ FILE* file = fopen(path, "r"); if (!file) { // 处理错误:权限不足或线程不存在 return; } char buffer[1024]; if (fgets(buffer, sizeof(buffer), file) == NULL) { // 读取失败 fclose(file); return; } fclose(file); ``` #### 4. 解析`stat`字段 ```c++ long utime, stime; // 用户态和内核态CPU时间(单位:时钟滴答) int cpu_id; char state; sscanf(buffer, "%*d %*s %c %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d " "%ld %ld %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %d", &state, &utime, &stime, &cpu_id); ``` --- ### 三、权限问题处理 - **Android限制**:普通应用只能访问`/proc/self/`(当前进程)或相同UID的进程。 - **解决方案**: - 仅监控本进程的线程(使用`/proc/self/task/`) - Root设备:通过`su`提权访问其他进程 --- ### 四、完整代码示例 ```c++ #include <stdio.h> #include <sys/syscall.h> #include <unistd.h> void read_thread_stat(int pid, int tid) { char path[64]; snprintf(path, sizeof(path), "/proc/%d/task/%d/stat", pid, tid); FILE* file = fopen(path, "r"); if (!file) { perror("Failed to open stat file"); return; } char buffer[512]; if (fgets(buffer, sizeof(buffer), file)) { long utime, stime; int cpu_id; char state; sscanf(buffer, "%*d %*s %c %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d " "%ld %ld %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %d", &state, &utime, &stime, &cpu_id); printf("State: %c, CPU: %d, UserTime: %ld, KernelTime: %ld\n", state, cpu_id, utime, stime); } fclose(file); } // 获取当前进程的主线程信息 void read_current_thread() { int pid = getpid(); int tid = syscall(SYS_gettid); // 直接调用gettid可能需API Level≥21 read_thread_stat(pid, tid); } ``` --- ### 五、注意事项 1. **字段顺序**:`/proc/[pid]/stat`字段位置固定,需参考内核文档(如[proc manpage](https://man7.org/linux/man-pages/man5/proc.5.html))。 2. **时钟滴答转秒**: ```c++ long clock_ticks_per_sec = sysconf(_SC_CLK_TCK); double cpu_usage_sec = (utime + stime) / (double)clock_ticks_per_sec; ``` 3. **多线程遍历**: 遍历`/proc/[pid]/task/`目录获取所有线程TID。 --- ### 六、替代方案 - **使用`syscall`直接调用`stat64`**: ```c++ #include <sys/stat.h> struct stat64 file_stat; if (syscall(SYS_stat64, "/proc/self/stat", &file_stat) == 0) { printf("File size: %lld\n", (long long)file_stat.st_size); } ``` --- 通过以上方法,你可以在NDK中实现进程/线程信息的监控,适用于性能分析或资源统计场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值