内核源码阅读(四)进程ID

来源:互联网 发布:桌面世界时钟软件 编辑:程序博客网 时间:2024/05/22 15:17

1)进程ID
进程ID,简称PID,是进程在命名空间的唯一表示。
线程组ID:每个进程除了PID这个特征值外,还有线程组ID(TGID),若没有使用线程,则PID和TGID相同。
会话ID(SID):几个进程可合并成一个会话,会话中所有进程都有同样的SID保存于task_struct的session成员中,可使用setsid系统调用设置。
进程组ID(PGRP):独立进程可合并成进程组,进程组内成员进程组ID都相同。
2)全局ID和局部ID
全局ID是内核本身和初始命名空间中的唯一ID号,早系统启动时开始的init进程就属于初始命名空间。
局部ID:局部ID属于某个特定的命名空间,不具备全局有效性。
3)管理PID
pid命名空间的表示如下所示

struct pid_namespace {         struct kref kref; /* 指向该命名空间指针的个数*/        struct pidmap pidmap[PIDMAP_ENTRIES]; /*表示分配pid的位图。当需要分配一个新的pid时只需查找位图,找到bit为0的位置并置1,然后更新统计数据域*/        int last_pid;  /*pidmap的分配。指向最后一个分配的pid的位置*/        struct task_struct *child_reaper;/*指向孤儿进程的指针*/         struct kmem_cache *pid_cachep;  /*指向分配pid的slab的地址。*/        unsigned int level; /* 命名空间的深度,初始值为0,依次增加*/        struct pid_namespace *parent; /* 指向父命名空间的指针 */#ifdef CONFIG_PROC_FS         struct vfsmount *proc_mnt; #endif }; 

其中struct pidmap的结构如下:

struct pidmap {  atomic_t nr_free;  /* 还能分配的pid的数量  */void *page;  /* 存放pid的物理页 */};

其中对于PID的管理主要围绕struct pid(内核对PID的内部表示)和struct upid(特定命名空间可见的信息)两个结构展开。其定义如下:

struct pid  {  atomic_t count;  /* 指向该数据结构的引用次数*/unsigned int level;  /* 该pid在pid_namespace中处于第几层*/ struct hlist_head tasks[PIDTYPE_MAX];  /* 指向的是一个哈希表*/struct rcu_head rcu;  /*通用文件对象指针的链表*/struct upid numbers[1];  /*numbers[i]表示第i层namespace*/}

下述联合体中各个成员分别对应
tasks[PIDTYPE_MAX]数组中每个元素都代表了不同的含义

enum pid_type  {  PIDTYPE_PID,  /*代表进程描述符(PID)*/PIDTYPE_PGID,  /*代表一组进程描述符*/PIDTYPE_SID,  /*组描述符再做一个群组,形成一个session*/PIDTYPE_MAX  /*pid所表示的类型的最大数*/};

下图为实现命名空间的ID表示所用的数据结构。
这里写图片描述

PID之间散列表的联系使用的是task_struct中的成员 struct pid_link pids[PIDTYPE_MAX],其中struct pid_link结构定义如下:

struct pid_link  {  struct hlist_node node;  /*散列表元素*/struct pid *pid;  /* 进程所属的pid结构实例 */};  
原创粉丝点击