1、进程的基本信息
1.1 标识一个进程——PID
每个进程都必须拥有它自己的进程描述符;
因此,即使共享内核大部分数据结构的轻量级进程(后面会提到),
也有它们自己的task_struct结构。
进程和进程描述符之间有非常严格的一一对应关系,所以我们可以方便地使用32位进程描述符地址标识进程。
进程描述符指针(task_struct*)指向这些地址。内核对进程的大部份引用都是通过进程描述符指针进行的。
另一方面,类Unix橾作系统允许用户使用一个叫做进程标识符processID (PID)的数来标识进程,PID存放在task_struct的pid字段中。
PID被顺序编号,新创建进程的PID通常是前一个进程的PID加1。
过,PID的值有一个上限,当内核使用的PID达到这个峰值的时候,就必须开始循环使用已闲置的小PID号。在缺省情况下,最大的PID号是32767
系统管理员可以通过往/proc/sys/kernel/pid_max 这个文件中写入一个更小的值来减小PID的上限值,使PID的上限小于32767。在64位体系结构中,系统管理员可以把PID的上限扩大到4194304。
由于循环使用PID编号,内核必须通过管理一个pidmap_array位图来表示当前已分配的PID和闲置的PID号。
因为一个页框包含32768个位(410248),所以在32位体系结构中pidmap_array位图正好存放在一个单独的页中。
系统会一直保存这些页而不释放的。
Linux只支持轻量级进程,不支持线程,但为了弥补这样的缺陷,Linux引入线程组的概念。
一个线程组中的所有线程使用和该线程组的领头线程相同的PID,
也就是该组中第一个轻量级进程的PID,它被存入进程描述符的tgid字段中。
getpid()系统调用返回当前进程的tgid值而不是pid值,
因此,一个多线程应用的所有线程共享相同的PID。
绝大多数进程都属于一个线程组;
而线程组的领头线程其tgid与pid的值相同,
因而getpid()系统调用对这类进程所起的作用和一般进程是一样的。
Linux虽不支持线程,但是它有具备支持线程的操作系统的所有特性,后面讲解轻量级进程的概念中还会详细讨论。
1.2 进程描述符定位
我们需要在3G之上线性地址的内存区为每个进程设计一个块——thread_union。
对每个进程来说,我们需要给其分配两个页面,即8192个字节的块。
Linu