linux 线程 编译,linux多线程编译 Linux标识进程(5)
3、getpid是如何实现的?
当陷入内核后,我们很容易获取当前的task struct(根据sp_svc的值),这是起点,后续的代码如下:
static inline pid_t task_tgid_vnr(struct task_struct *tsk)
{
return pid_vnr(task_tgid(tsk));
}
通过task_tgid可以获取该task对应的thread group leader的thread ID,其实也就是process ID。此外,通过task_active_pid_ns亦可以获取当前的pid namespace,有了这两个参数,可以调用pid_nr_ns获取该task对应的pid number:
pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
{
struct upid *upid;
pid_t nr = 0;
if (pid && ns->level <= pid->level) {
upid = &pid->numbers[ns->level];
if (upid->ns == ns)
nr = upid->nr;
}
return nr;
}

一个pid可以贯穿多个pid namespace,但是并非所有的pid namespace都可以检视pid,获取相应的pid number。因此,在代码的开始会进行验证,如果pid namespace的层次(ns->level)低于pid当前的pid namespace的层次,那么直接返回0。如果pid namespace的level是OK的,那么要检查该namespace是不是pid当前的那个pid namespace,如果是,直接返回对应的pid number,否则,返回0。
对于gettid和getppid这两个接口,整体的概念是和getpid类似的,不再赘述。
4、给定线程ID number的情况下,如何找对应的task struct?
这里给定的条件包括ID number、当前的pid namespace,在这样的条件下如何找到对应的task呢?我们分成两个步骤,第一个步骤是先找到对应的struct pid,代码如下:
struct pid *find_pid_ns(int nr, struct pid_namespace *ns)
{
struct upid *pnr;
hlist_for_each_entry_rcu(pnr,
&pid_hash[pid_hashfn(nr, ns)], pid_chain)
if (pnr->nr == nr && pnr->ns == ns)
return container_of(pnr, struct pid,
numbers[ns->level]);
return NULL;
}
整个系统有那么多的struct pid数据对象,每一个pid又有多个level的(pid namespace,pid number)对,通过pid number和namespace来找对应的pid是一件非常耗时的操作。此外,这样的操作是一个比较频繁的操作,一个简单的例子就是通过kill向指定进程(pid number)发送信号。正是由于操作频繁而且耗时,系统建立了一个全局的哈希链表来解决这个问题,pid_hash指向了若干(具体head的数量和内存配置有关)哈希链表头。这个哈希表用来通过一个指定pid namespace和id number,来找到对应的struct upid。linux多线程编译一旦找了upid,那么通过container_of找到对应的struct pid数据对象。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-76987-5.html
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
