当进程被新建时,内核会给进程分配一个8K的空间作为进程的内核堆栈。同时我们知道task_struct结构体也会被创建,但有意思的是,内核不会给task_struct单独分别空间,而是直接将其扔到8k的内核堆栈中,与内核堆栈共享这8K内存。 

假设我们用如下结构表示进程描述符和内核堆栈: 

struct task_struct task; 

unsigned long stack [INIT_TASK_SIZE/sizeof(long)]; 

那么我们很容易将其做成一个联合体: 

union task_union { 

        struct task_struct task; 

        unsigned long stack[INIT_TASK_SIZE/sizeof(long)]; 

}; 

实际上,进程创建时内核会分配2个连续的页面(8192byte),将其底部大约1k(960byte)的空间拿来存放进程描述符(task_struct),上部大约7k(7232byte)的空间拿来作为内核堆栈。(更多,参考这里和这里) 

内核不会让内核堆栈超出7232byte,否则会覆盖task_struct而导致错误。 

在内核空间(kernel space)中,有一个专门的全局数组来保存所有的进程描述符(指针),数组条目就是上面的task_union的指针, 这个数组称为Task Array。 

很明显的一个问题:pid的最大值是32767,而系统允许的最大进程数是512,如果用pid作为Task Array的索引而将数组大小设为32768的话,数组空间上存在明显的浪费。实际上Task Array的实际大小是系统允许的最大进程数,而内核采用了一些其他的算法(???)将进程描述符分布到数组中去。 

现在,如果我们想遍历系统中所有的进程,由于一般情况下Task数组中的大多数元素都是空的,所以下面的代码是低效的: 

for ( i=; i<NR_TASKS; i++ ) 

{ 

if (task[i]) 

//do something 

} 

为此,task_struct结构体中加了如下字段:struct task_struct *next_task, *prev_task; 分别指向上一个进程和下一个进程,那么所有进程在连接在一起便形成了一个双向循环链表(double circular linked list),这样的遍历就变得高效了。该链表的头和尾都始终是init进程,因为init进程是长期存在的,这能保证链表一直有效。 

随着进程的创建,我们需要在Task数组中找到空闲位置而将新进程插入进去。遍历Task数组的方式是可行却低效的,一个很简单的方式是准备一个堆栈(数据结构上的stack),让栈持有Task数组空闲位置的指针。当你需要插入新元素Task数组时,弹出栈顶元素供你使用便可;当你从Task数组中删除元素后,将该空闲位置压栈以便下次使用。而这个栈,就是linux中的tarray_freelist (自由时间列表) 

试想如下case,进程p1要kill进程p2: 

p1: kill - pidOfP2 

此时系统如何通过p2的PID找到p2的进程描述符?遍历task数组或遍历task_struct形成的双向循环链表都是低下的。 

快速查找的一个简单方案是散列表(hash table),这个散列表称为pidhash,该表以pid为键(key),以指向pid对应的进程描述符的指针为值(value)。散列算法为: 

#define pid_hashfn(x) ((((x)>>8) ^ (x)) & (PIDHASH_SZ-1)) 

其中PIDHASH_SZ为系统定义的此散列表的大小。 

pidhash解决碰撞(冲突,colliding)的算法是“链接表法” 

(扩展, 其实效率最高的做法是直接通过pid做索引而用普通数组,只所以用散列表,道理和Task数组一样:节约空间) 

linux进程学习-进程描述符的存储的更多相关文章

  1. Linux中的文件描述符与打开文件之间的关系

    Linux中的文件描述符与打开文件之间的关系 导读 内核(kernel)利用文件描述符(file descriptor)来访问文件.文件描述符是非负整数.打开现存文件或新建文件时,内核会返回一个文件描 ...

  2. Linux中的文件描述符与打开文件之间的关系------------每天进步一点点系列

    http://blog.csdn.net/cywosp/article/details/38965239 1. 概述     在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件.目录文件. ...

  3. (转)Linux中的文件描述符

    本文转自:http://blog.csdn.net/cywosp/article/details/38965239 作者:cywosp 1. 概述 在Linux系统中一切皆可以看成是文件,文件又可分为 ...

  4. (转)Linux中的文件描述符与打开文件之间的关系

    转:http://blog.csdn.net/cywosp/article/details/38965239 1. 概述     在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件.目录文 ...

  5. Linux exec与文件描述符

    看到好几篇文章讲述exec都是一知半解,所以我尽量说的清楚明白一些.本文首先讲述Linux文件描述符,然后是exec,最后举例说明exec I/O重定向及其用法. 概念:exec命令用于调用并执行指令 ...

  6. Linux Linux下最大文件描述符设置

    Linux下最大文件描述符设置 by:授客 QQ:1033553122 1.   系统可打开最大文件描述符设置 查看系统可打开最大文件描述符 # cat /proc/sys/fs/file-max 6 ...

  7. [svc]linux中的文件描述符(file descriptor)和文件

    linux中的文件描述符(file descriptor)和文件 linux为了实现一切皆文件的设计哲学,不仅将数据抽象成了文件,也将一切操作和资源抽象成了文件,比如说硬件设备,socket,磁盘,进 ...

  8. linux fcntl 对文件描述符控制

    linux fcntl 对文件描述符控制 linux fcntl 对文件描述符控制 linux fcntl 对文件描述符控制

  9. linux进程学习-进程描述符,控制块

    从数据结构的角度,进程用task_struct结构来描述,称为“进程描述符 (Process Descriptor)”或者“进程控制块(Process Control Block, PCB)”,其包含 ...

随机推荐

  1. mysql导出导入所有数据库

    导出所有数据库 mysqldump -uroot -p123456 --all-databases > /home/aa.sql 导入所有数据库 mysql -uroot -p123456 &l ...

  2. eclipse中查看java源代码设置方法

    众所周知,第一次查看class文件时,eclipse会给个界面选择添加源代码路径.   但是,如果我要换源代码路径了怎么办,eclipse也不会提示了.那就使用手动的吧       方法1: 使用ec ...

  3. python中executemany的使用

    conn = MySQLdb.connect(host = “localhost”, user = “root”, passwd = “password”, db = “myDB”, charset= ...

  4. 【阿里云】Windows2008 FTP配置指南

    云服务器默认使用Windws 2008 IIS 中自带的FTP服务器.    1.添加FTP帐号    A. 选择[服务管理器]--[配置]--[本地用户和组]--[用户]:在空白处右键选择[新用户] ...

  5. syslog,rsyslog and syslog-ng

    http://en.wikipedia.org/wiki/Syslog Syslog is a standard for computer message logging. It permits se ...

  6. Lua学习九----------Lua字符串

    © 版权声明:本文为博主原创文章,转载请注明出处 1.Lua字符串 - ''单引号间的一串字符 - ""双引号之间的一串字符 - [[]]之间的一串字符 2.Lua转义字符 3.字 ...

  7. 【WPF学习笔记】之如何点击“新建”按钮,在面板中加载一条条的“用户控件”的信息:动画系列之(四)

    ...... 承接上一系列动画三. 在主界面后台代码设置嵌套第二个用户控件. using System; using System.Collections.Generic; using System. ...

  8. Cesium--气泡弹窗

    参考资料 首先感谢以下博主们的帮助,本人刚接触Cesium不久,无奈只能拾人牙慧了. 由于cesium没有自带的点击弹出气泡的功能,所以需要自己去开发一个这样的功能,网络上资源很多,看到基本思路都一致 ...

  9. Python学习总结之五 -- 入门函数式编程

    函数式编程 最近对Python的学习有些怠慢,最近的学习态度和学习效率确实很不好,目前这种病况正在好转. 今天,我把之前学过的Python中函数式编程简单总结一下,分享给大家,也欢迎并感谢大家提出意见 ...

  10. Unity3D研究院编辑器之脚本设置ToolBar及脚本设置顶视图

    Unity版本5.3.2 如下图所示,ToolBar就是Unity顶部的那一横条.这里的所有按钮一般情况下都得我们手动的用鼠标去点击.这篇文章我们说说如果自动操作它们 1.自动点击左边四个按钮 (拖动 ...