PID即进程描述符在linux kernel中的分配和管理比较复杂。 本文分析了其相关数据结构以及函数。 (代码基于v3.0.3)
和PID相关的数据结构有
struct pid
{
atomic_t count;
unsigned int level;
struct hlist_head tasks[PIDTYPE_MAX];
struct rcu_head rcu;
struct upid numbers[1];
};
其中 count是指向该数据结构的引用次数。
level是该pid在pid_namespace中处于第几层。当level=0时表示是global namespace,即最高层。pid_namespace这个数据结构将在后面进行解释。
tasks[PIDTYPE_MAX]数组中每个元素都代表了不同的含义。PIDTYPE_MAX表示pid所表示的类型的最大数。 该值定义在enum pid_type中
enum pid_type
{
PIDTYPE_PID,
PIDTYPE_PGID,
PIDTYPE_SID,
PIDTYPE_MAX
};
PIDTYPE_PID代表进程描述符(PID) 。 PIDTYPE_PGID代表一组进程描述符。 一组进程(process)可以组成一个群组,并且有一个组描述符。 这样的好处是如果有一个信号是针对这个组描述符,该群组内的所有进程都可以接受到。 PIDTYPE_SID是对组描述符再做一个群组,形成一个session。这是更高一个层次的抽象。
tasks[i]指向的是一个哈希表。譬如说tasks[PIDTYPE_PID]指向的是PID的哈希表。
rcu域我也没有搞明白到底是做什么的:(
numbers[1]域指向的是upid结构体。 numbers数组的本意是想表示不同的pid_namespace。 一个PID可以属于不同的namespace, numbers[0]表示global namespace,numbers[i]表示第i层namespace,i越大所在层级越低。目前该数组只有一个元素, 即global namespace。所以namepace的概念虽然引入了pid,但是并未真正使用,在未来的版本可能会用到。
接下来我们再看看upid这个数据结构
struct upid {
int nr;
struct pid_namespace × ns;
struct hlist_node pid_chain;
};
pid结构体中的numbers域指向了upid结构体。该结构体中
nr是pid的值, 即 task_struct中 pid_t p