struct pid有三个链表头,如果该pid仅仅是标识一个thread ID,那么其pid链表头指向的链表中只有一个元素,就是使用该pid的task struct。如果该pid表示的是一个process ID,那么pid链表头指向的链表中多个task struct,每一个元素表示了属于该进程的线程的task struct,链表中第一个task struct是thread group leader。linux多线程编译如果该pid并不表示一个process group ID或者session ID,那么struct pid中的pgid链表头和session链表头都是指向null。如果该pid表示一个process group ID的时候,其结构如下图所示:

对于那些multi-thread进程,内核有若干个task struct和进程对应,不过为了简单,在上面图片中,进程x 对应的task struct实际上是thread group leader对应的那个task struct。这些task struct的pgid指针(task->pids[PIDTYPE_PGID].pid)指向了该进程组对应的struct pid数据对象。而该pid中的pgid链表头串联了所有使用该pid的task struct(仅仅是串联thread group leader对应的那些task struct),而链表中的第一个节点就是进程组leader。
session pid的概念是类似的,大家可以自行了解学习。
4、如何抽象 pid namespace?
好吧,这个有点复杂,暂时TODO吧。
五、代码分析
1、如何根据一个task struct得到其对应的thread ID?
static inline struct pid *task_pid(struct task_struct *task)
{
return task->pids[PIDTYPE_PID].pid;
}
同样的道理,我们也可以很容易得到一个task对应的pgid和sid。process ID有一点绕,我们首先要找到该task的thread group leader对应的task,其实一个线程的thread group leader对应的那个task的thread ID就是该线程的process ID。
2、如何根据一个task struct得到当前的pid namespace?
struct pid_namespace *task_active_pid_ns(struct task_struct *tsk)
{
return ns_of_pid(task_pid(tsk));
}
这个操作可以分成两步,第一步首先找到其对应的thread ID,然后根据thread ID找到当前的pid namespace,代码如下:
static inline struct pid_namespace *ns_of_pid(struct pid *pid)
{
struct pid_namespace *ns = NULL;
if (pid)
ns = pid->numbers[pid->level].ns;
return ns;
}
一个struct pid实体是有层次的,对应了若干层次的(pid namespace,pid number)二元组,最顶层是root pid namespace,最底层(叶节点)是当前的pid namespace,pid->level表示了当前的层次,因此pid->numbers[pid->level].ns说明的就是当前的pid namespace。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-76987-4.html
请不起灯光师
台湾同胞抗议台独
我们也要巡航才对吗
查出来告他诈骗