linux系统中每个进程由一个进程id标识,在内核中对应一个task_struct结构的进程描述符,系统中所有进程的task_struct通过链表链接在一起,在内核中,经常需要通过进程id来获取进程描述符,最简单的方法可以通过遍历task_struct链表并对比id的值来获取,但这样效率太低,尤其当系统中运行很多个进程的时候。
linux内核通过PID散列表来解决这一问题,能快速的通过进程ID获取到进程描述符。
PID散列表包含4个表,因为进程描述符包含了表示不同类型PID的字段,每种类型的PID需要自己的散列表。
enum pid_type { PIDTYPE_PID, // 进程的PID PIDTYPE_TGID, // 线程组领头进程的PID PIDTYPE_PGID, // 进程组领头进程的PID PIDTYPE_SID, // 会话领头进程的PID PIDTYPE_MAX // 类型个数 };
查看/proc/pid/status可以看到一些进程的当前状态:
shell@android:/proc/19280/task $ cat 19282/status Name: GC State: S (sleeping) Tgid: 19280 Pid: 19282 PPid: 17974 TracerPid: 0 Uid: 10043 10043 10043 10043 Gid: 10043 10043 10043 10043 FDSize: 256 Groups: 1006 1007 1015 1028 3001 3002 3003 VmPeak: 483560 kB VmSize: 481500 kB VmLck: 0 kB VmPin: 0 kB VmHWM: 44940 kB VmRSS: 29684 kB VmData: 24848 kB VmStk: 136 kB VmExe: 8 kB VmLib: 29096 kB VmPTE: 160 kB VmSwap: 0 kB Threads: 19 SigQ: 0/5987 SigPnd: 0000000000000000 ShdPnd: 0000000000000000 SigBlk: 0000000000001204 SigIgn: 0000000000000000 SigCgt: 00000002000094e8 CapInh: 0000000000000000 CapPrm: 0000000000000000 CapEff: 0000000000000000 CapBnd: ffffffffffffffff Cpus_allowed: 3 Cpus_allowed_list: 0-1 voluntary_ctxt_switches: 5 nonvoluntary_ctxt_switches: 33