在proc文件系统中有对每个进程维护一个目录/proc/$PID/,其中的/proc/$PID/stat文件展示了该进程的状态。
在某及其上的某进程状态如下
1 2 3 4 |
[root@vt-nhm9 ~]# cat /proc/7021/stat 7021 (gnome-session) S 6903 6874 6229 0 -1 4202752 3672 16747 60 30 6 3 14 5 20 0 2 0 3833 251568128 1572 18446744073709551615 4194304 4411596 140734229412352 140734229411488 265399685603 0 0 4100 83707 18446744073709551615 0 0 17 0 0 0 123 0 0 6508752 6536912 6537216 [root@vt-nhm9 ~]# uname -a Linux vt-nhm9 3.4.0-rc4+ #1 SMP Thu May 3 14:53:37 CST 2012 x86_64 x86_64 x86_64 GNU/Linux |
对/proc/$PID/stat的解释如下:(在最新的Linux kernel 3.4.0,在2.6.32中也是类似的)
第1列 表示进程的PID
第2列 表示进程的名称
第3列 表示进程的状态 (这里的S表示Sleep,关于进程的状态,可以后续再来篇博客介绍一下)
第4列 表示进程的PPID,即父进程的PID
……
第18列 表示进程的优先级
第19列 表示进程的nice值
第20列 表示进程的线程数量
第21列 (已被硬编码为0) The time in jiffies before the next SIGALRM is sent to the process due to an interval timer.
第22列 表示进程的启动时间,这个时间是用jiffies表示的从系统启动到进程启动的时间。The time in jiffies the process started after system boot.
……
我前面有文章“”用到了第22列(进程的启动时间),它的值需要除以$(getconf CLK_TCK)的值才能得到以秒为单位的(从系统启动到进程启动)的时间间隔。
/proc/$PID/stat的输出结构,可以在kernel代码的fs/proc/array.c文件中去查看。下面简单看一下array.c这个文件:
在Linux3.4.0中,fs/proc/array.c中的do_task_stat函数中将打印某个进程的status.可以看到第22个位进程的开始时间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, struct pid *pid, struct task_struct *task, int whole) { unsigned long vsize, eip, esp, wchan = ~0UL; long priority, nice; int tty_pgrp = -1, tty_nr = 0; /* omitting many codes.. */ seq_printf(m, "%d (%s) %c", pid_nr_ns(pid, ns), tcomm, state); seq_put_decimal_ll(m, ' ', ppid); seq_put_decimal_ll(m, ' ', pgid); seq_put_decimal_ll(m, ' ', sid); seq_put_decimal_ll(m, ' ', tty_nr); seq_put_decimal_ll(m, ' ', tty_pgrp); seq_put_decimal_ull(m, ' ', task->flags); seq_put_decimal_ull(m, ' ', min_flt); seq_put_decimal_ull(m, ' ', cmin_flt); seq_put_decimal_ull(m, ' ', maj_flt); seq_put_decimal_ull(m, ' ', cmaj_flt); seq_put_decimal_ull(m, ' ', cputime_to_clock_t(utime)); seq_put_decimal_ull(m, ' ', cputime_to_clock_t(stime)); seq_put_decimal_ll(m, ' ', cputime_to_clock_t(cutime)); seq_put_decimal_ll(m, ' ', cputime_to_clock_t(cstime)); seq_put_decimal_ll(m, ' ', priority); seq_put_decimal_ll(m, ' ', nice); seq_put_decimal_ll(m, ' ', num_threads); seq_put_decimal_ull(m, ' ', 0); seq_put_decimal_ull(m, ' ', start_time); seq_put_decimal_ull(m, ' ', vsize); seq_put_decimal_ll(m, ' ', mm ? get_mm_rss(mm) : 0); seq_put_decimal_ull(m, ' ', rsslim); seq_put_decimal_ull(m, ' ', mm ? (permitted ? mm->start_code : 1) : 0); seq_put_decimal_ull(m, ' ', mm ? (permitted ? mm->end_code : 1) : 0); seq_put_decimal_ull(m, ' ', (permitted && mm) ? mm->start_stack : 0); seq_put_decimal_ull(m, ' ', esp); /* omitting many codes.. */ } |
关于/proc/$PID/stat的信息,可以man proc得到更多的详细解释。