linux进程学习-进程描述符的存储
当进程被新建时,内核会给进程分配一个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进程学习-进程描述符的存储的更多相关文章
- Linux中的文件描述符与打开文件之间的关系
Linux中的文件描述符与打开文件之间的关系 导读 内核(kernel)利用文件描述符(file descriptor)来访问文件.文件描述符是非负整数.打开现存文件或新建文件时,内核会返回一个文件描 ...
- Linux中的文件描述符与打开文件之间的关系------------每天进步一点点系列
http://blog.csdn.net/cywosp/article/details/38965239 1. 概述 在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件.目录文件. ...
- (转)Linux中的文件描述符
本文转自:http://blog.csdn.net/cywosp/article/details/38965239 作者:cywosp 1. 概述 在Linux系统中一切皆可以看成是文件,文件又可分为 ...
- (转)Linux中的文件描述符与打开文件之间的关系
转:http://blog.csdn.net/cywosp/article/details/38965239 1. 概述 在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件.目录文 ...
- Linux exec与文件描述符
看到好几篇文章讲述exec都是一知半解,所以我尽量说的清楚明白一些.本文首先讲述Linux文件描述符,然后是exec,最后举例说明exec I/O重定向及其用法. 概念:exec命令用于调用并执行指令 ...
- Linux Linux下最大文件描述符设置
Linux下最大文件描述符设置 by:授客 QQ:1033553122 1. 系统可打开最大文件描述符设置 查看系统可打开最大文件描述符 # cat /proc/sys/fs/file-max 6 ...
- [svc]linux中的文件描述符(file descriptor)和文件
linux中的文件描述符(file descriptor)和文件 linux为了实现一切皆文件的设计哲学,不仅将数据抽象成了文件,也将一切操作和资源抽象成了文件,比如说硬件设备,socket,磁盘,进 ...
- linux fcntl 对文件描述符控制
linux fcntl 对文件描述符控制 linux fcntl 对文件描述符控制 linux fcntl 对文件描述符控制
- linux进程学习-进程描述符,控制块
从数据结构的角度,进程用task_struct结构来描述,称为“进程描述符 (Process Descriptor)”或者“进程控制块(Process Control Block, PCB)”,其包含 ...
随机推荐
- 3、C++新的关键字
C++ 添加了一些全新的关键字. 1.new new 来进行动态内存的分配,而delect 则是进行内存的释放, 申请的方式: 变量申请: int *p = new int; // 申 ...
- 转:3.3V和5V电平双向转换——NMOS管
分简单,仅由3个电阻加一个MOS管构成,电路图如下: 此电路来自于飞利浦的一篇设计指导文档,是I2C总线官方推荐使用的电平转换电路.在实际使用过程中,需要尤其注意NMOS管的选型以及上拉电阻阻值的选取 ...
- 使用sphinx生成美观的文档
先上效果图 详情 首先,须要知道什么是restructuredtext.能够理解为类似于markdown的一个东西. 然后 安装.pip install sphinx 进入存放文档的文件夹,在命令行, ...
- HDU 3461 Code Lock(并查集的应用+高速幂)
* 65536kb,仅仅能开到1.76*10^7大小的数组. 而题目的N取到了10^7.我開始做的时候没注意,用了按秩合并,uset+rank达到了2*10^7所以MLE,所以貌似不能用按秩合并. 事 ...
- 最短路 uva12661 Funny Car Racing
传送门:点击打开链接 题意:给你有向图,每条边呈周期性开放,即开放a时间,再关闭b时间.再开放a时间以此类推 假设时间不足以穿过这条路则不能走.你能够在节点等待时间,问从s走到t所须要的最小时间 细致 ...
- jquery垂直滚动插件一个参数用于设置速度,兼容ie6
利用外层的块级元素负外边距来滚动 1.使用 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://ww ...
- jquery插件函数传参错误
1.jquery传参通过json,可能的错误是,参数中的结束符写成了;
- 查看mysql 的存储过程定义
查询数据库中的存储过程 方法一: select `name` from mysql.proc where db = 'your_db_name' and `type` = 'PROCEDURE' 方法 ...
- mac环境下清理系统垃圾clearMyMac 3.9 破解版
mac环境下清理系统垃圾clearMyMac 3 轻轻松松清理好几十G的垃圾文件 下载地址 链接: https://pan.baidu.com/s/1XZbZwzhgQCnzpvQDvyQrRA 密码 ...
- Azure、数据、AI开发工具
Azure.数据.AI开发工具 在今天召开的 Connect(); 2017 开发者大会上,微软宣布了 Azure.数据.AI 开发工具的内容.这是第一天的 Connect(); 2017 的主题演讲 ...