进程间关系有父子、兄弟关系,task_struct中由real_parent、parent、children、sibling四个分量表示,real_parent和parent是task_struct指针,指向父进程,real_parent和parent的不同在于ptrace。
系统中的0号和1号进程由内核创建,0号进程为内核进程,1号进程为用户进程,以root身份运行,所有其他用户进程的祖先进程。
其他的关系还包括:进程组组长、线程组组长、trace进程等。
pid哈希表
为了能通过pid快速定位到task_struct结构,内核使用哈希表来组织task_struct对象,采用拉链方式解决冲突。根据不同pid类型,分为4个哈希表,分别为PIDTYPE_PID PIDTYPE_TGID PIDTYPE_PGID PIDTYPE_SID,哈希表的表头根据物理内存的大小,是动态变化的,比如,512MB内存的机器,每个哈希表表头占4个页帧,包含2048个项。
从pid到哈希表索引的转换是通过下面的代码实现的(32位系统):
#define pid_hashfn(x) hash_long((unsigned long) x, pidhash_shift)
unsigned long hash_long(unsigned long val, unsigned int bits)
{
unsigned long hash = val * 0x9e370001UL;
return hash >> (32 - bits);
}
pidhash_shift为11,该哈希函数可以获得0-2^11范围的哈希值。
0x9e370001为32位系统中一个接近0-2^32黄金分割点的素数,该值可以通过简单的移位和加减运算得到:
2^31 + 2^29 -2^25 + 2^22 - 2^19 - 2^16 + 1
(可参见《算法导论》中关于哈希函数选择的讨论)
pid哈希表采用拉链法解决冲突,使用list.h中的struct hlist_node和struct hlist_head完成。
后续:3.2.4 进程是如何被组织的
阅读(2845) | 评论(0) | 转发(0) |