-
Notifications
You must be signed in to change notification settings - Fork 1
/
内核角度看操作系统
32 lines (31 loc) · 2.34 KB
/
内核角度看操作系统
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
进程标识符
能被独立调度的每个执行上下文都必须拥有它自己的进程的描述符。内核使用task_structi表示。
进程与进程描述符有着一对一的关系。
进程描述符中 有个字段 叫做 进程标识符PID。PID被顺序编号,PID有上限,循环使用闲置的PID。
正是由于 PID的循环使用 所以需要使用pidmap-array位图来表示使用的PID和闲置的PID,位图单独消耗一个页。
一个线程组有着同样的PID,也是该线程组的第一个轻量级的PID,他被存放于 进程描述符的tgid字段中。getPID()调用
返回的是tgid的值 而不是PID。
进程描述符的处理
进程的描述符存放在动态内存中,LInux为每个进程分配了两个区域,一个是进程的堆栈,一个是thread_info(线程描述符),占用两个连续的页。
esp寄存器是CPU栈指针,用来存放栈顶单元。栈起于末端 向下生长。用户态切换到内核态时,此时栈是空的,esp寄存器指向栈的顶端。
在内核中,使用一个联合结构体表示 一个进程的线程描述符和内核栈。
/**
* 内核栈与thread_info的联合体。
*/
union thread_union {
struct thread_info thread_info;
unsigned long stack[THREAD_SIZE/sizeof(long)];
};
进程与内核堆栈紧密接触的好处:内核很容易从esp寄存器的值获得当前CPU上正在运行进程的thread_info结构的地址。
进程间的关系
进程0 和进程1 是是由内核创建的, 进程1 是所有进程的祖先。
pidhash表及链表
内核为了快速的通过 pid找到对应的进程描述符指针,将其放到四个hash表中
kill()系统调用过程:如 p1调用要杀死p2 。 kill pid,内核通过pid导出 其对应的进程描述符,然后从p2的进程描述符中取出记录挂起信号的数据结构指针。
进程资源限制
每个进程都有一组相关的资源限制,限定了进程能使用的系统资源数量。避免过分使用系统资源。
进程地址空间的最大数,CPU的最长时间,堆大小的最大值,文件大小的最大值,文件锁的最大值等待
进程切换
内核必须有能力挂起正在CPU上运行的某个进程的执行,然后恢复另一个进程的执行,就叫做进程的切换。
硬件上下文
每个进程有着拥有属于自己的地址空间,所有进程必须共享CPU寄存器。