分类: LINUX
2011-03-08 09:01:33
内核通过一个惟一的进程标识值(process identification value)或PID来标识每个进程。PID是一个数,表示为pid_t隐含类型,实际上就是一个int类型。为了与老版本的Unix和Linux兼容,PID的最大值默认设置为32768(short int短整型的最大值),尽管这个值也可以增加到类型所允许的范围。内核把每个进程的PID存放在它们各自的进程描述符中。
这个最大值很重要,因为它实际上就是系统中允许同时存在的进程的最大数目。尽管32768对于一般的桌面系统足够用了,但是大型服务器可能需要更多进程。这个值越小,转一圈就越快,本来数值大的进程比数值小的进程迟运行,但这样一来就破坏了这一原则。如果确实需要的话,可以不考虑与老式系统的兼容,由系统管理员通过修改/proc/sys/kernel/pid_max来提高上限。
在内核中,访问任务通常需要获得指向其task_struct指针。实际上,内核中大部分处理进程的代码都是直接通过task_struct进行的。因此,通过current宏查找到当前正在运行进程的进程描述符的速度就显得尤为重要。硬件体系结构不同,该宏的实现也不同,它必须针对专门的硬件体系结构做处理。有的硬件体系结构可以拿出一个专门寄存器来存放指向当前进程task_struct的指针,用于加快访问速度。而有些像x86这样的体系结构(其寄存器并不富余),就只能在内核栈的尾端创建thread_info结构,通过计算偏移间接地查找task_struct结构。
在x86系统上,current把栈指针的后13个有效位屏蔽掉,用来计算出thread_info的偏移。该操作通过current_thread_info()函数完成的。汇编代码如下:
这里假定栈的大小为8KB。当4KB的栈启用时,就要用4096,而不是8192。
最后,current再从thread_info的task域中提取并返回task_struct的地址:
对比一下这部分在PowerPC上的实现(IBM基于RISC的现代微处理器),我们可以发现当前task_struct的地址是保存在一个寄存器中的。也就是说,在PPC上,current宏只需把r2寄存器中的值返回就行了。与x86不一样,PPC有足够多的寄存器,所以它的实现有这样选择的余地。而访问进程描述符是一个重要的频繁操作,所以PPC的内核开发者觉得完全有必要为此使用一个专门的寄存器。