Chinaunix首页 | 论坛 | 博客
  • 博客访问: 412470
  • 博文数量: 65
  • 博客积分: 1491
  • 博客等级: 上尉
  • 技术积分: 702
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-30 15:57
文章分类
文章存档

2011年(6)

2010年(12)

2009年(47)

我的朋友

分类: LINUX

2009-11-17 11:32:01

Understanding the Linux Kernel : Chapter 3. Processes

以下内容为本人的阅读笔记:
注:参照了《Linux 内核源代码情景分析》的第一章和第二章内容。

(1)Processes are like human beings: they are generated, they have a more or less significant life, they optionally generate one or more child processes, and eventually they die. A small difference is that sex is not really common among processes each process has just one parent.

进程就像人一样,有生、死,有生活,有父母,甚至还有性。

(2)Although the parent and child may share the pages containing the program code (text), they have separate copies of the data (stack and heap), so that changes by the child to a memory location are invisible to the parent (and vice versa).

子进程从父进程继承到:code(text), 文件描述符等等.


(3)To manage processes, the kernel must have a clear picture of what each process is doing. This is the role of the process descriptor (a task_struct type structure) whose fields contain all the information related to a single process.

process descriptor 保存进程的全部有用信息。 

(4)Process descriptors (task_struct) stored in dynamic memory rather than in the memory area permanently assigned to the kernel. For each process, Linux packs two different data structures in a single per-process memory area: a small data structure linked to the process descriptor, namely the thread_info structure, and the Kernel Mode process stack. 

process descriptor 保存在 dynamic memory, 而内核需要一个 permanent memory (两者都在 Kernel memory)。因此 Linux 打包生成了两个数据结构:thread_info 和 Kernel stack。thread_info 指向 process descriptor,同时 process descriptor 也指向 thread_info,两者互为补充。

(5)The esp register is the CPU stack pointer, which is used to address the stack's top location. On 80x86 systems, the stack starts at the end and grows toward the beginning of the memory area. 

ESP寄存器的指针总是指向栈顶。
x86系统中,栈空间地址从内存区末端向内存区开始的方向增长。

(6)Process list is a doubly linked list that links together all existing process descriptors.
Each task_struct structure includes a tasks field of type list_head whose prev and next fields point, respectively, to the previous and to the next task_struct element.
The head of the process list is the init_task task_struct descriptor; it is the process descriptor of the so-called process 0 or swapper.

双向链表 Process list 连接所有的 process descriptors.

(7)The lists of TASK_RUNNING processes:Each task_struct descriptor includes a run_list field of type list_head. Linux can find a process to run on the cpu from this list.

链表 TASK_RUNNING processes 连接所有可运行的 processes.

(8)Scanning the process list sequentially and checking the pid fields of the process descriptors is feasible but rather inefficient. To speed up the search, four hash tables have been introduced (pid, tgid, pgrp, session). 

4类 PID 的 hash 表可用于快速的根据 PID 找到 process descriptors.

(9)Therefore, a wait queue represents a set of sleeping processes, which are woken up by the kernel when some condition becomes true.

wait queue 的定义。

(10)Each process has an associated set of resource limits , which specify the amount of system resources it can use.The resource limits for the current process are stored in the current->signal->rlim field, that is, in a field of the process's signal descriptor.
Most resource limits contain the value RLIM_INFINITY (0xffffffff), which means that no user limit is imposed on the corresponding resource.

每个进程都有一个结构体 signal descriptor 存储着资源限制,process descriptors 有指针指向这个结构体。

(11)Linux 2.6 uses software to perform a process switch rather than hardware context.
The contents of all registers used by a process in User Mode have already been saved on the Kernel Mode stack before performing process switching.

Linux 2.6 的切换方式是 software 而不是 hardware context.
Kernel Mode stack 保存 registers.

(12)The 80x86 architecture includes a specific segment type called the Task State Segment (TSS), to store hardware contexts. The tss_struct structure describes the format of the TSS. As already mentioned in Chapter 2, the init_tss array stores one TSS for each CPU on the system.

x86 的每一个 CPU 都对应有一个 TSS,用于保存 CPU 当前的 hardware context.

(13)Each process descriptor includes a field called thread of type thread_struct, in which the kernel saves (most of) the hardware context (from TSS) whenever the process is being switched out.

进程描述符中的 thread 字段实时保存着 hardware context (from TSS) 的大部分环境变量。
注:进程描述符中保存着进程的许多信息,用于进程进程切换时重新使用。

(14)clone( ), fork( ), and vfork( ).
fork( ) and vfork( ) are both implemented by clone( ) with different args. 

clone( ): 子进程根据参数有选择性地复制父进程的资源
fork( ): 子进程复制父进程的所有资源(Copy On Write technique)
vfork( ): 子进程除了task_struct 和 系统空间堆栈 外,不复制而只是用指针指向父进程的所有资源

(15)The ancestor of all processes, called process 0, the idle process, or, for historical reasons,the swapper process, is a kernel thread created from scratch during the initialization phase of Linux (see Appendix A). 
In multiprocessor systems there is a process 0 for each CPU. Right after the power-on, the BIOS of the computer starts a single CPU while disabling the others. The swapper process running on CPU 0 initializes the kernel data structures, then enables the other CPUs and creates the additional swapper processes

process 0 实际上是一个内核线程,在内核初始化时产生。

(16)The C compiler always inserts an exit( ) function call right after the last statement of the main( ) function.

C 编译器总是在 main() 函数的最后面插入 exit() 语句。

(17)The Unix operating system allows a process to query the kernel to obtain the PID of its parent process or the execution state of any of its children. A process may, for instance, create a child process to perform a specific task and then invoke some wait( )-like library function to check whether the child has terminated.

内核允许进程获得其父进程或子进程的进程ID。
wait( )系列函数便是父进程用于检查子进程是否结束的函数。

(18)although the process is technically dead, its descriptor must be saved until the parent process is notified.
What happens if parent processes terminate before their children? In such a case, the system could be flooded with zombie processes whose process descriptors would stay forever in RAM. 

子进程结束却未被父进程得知(使用 wait 系列函数)的情况下,子进程的 descriptor 会永远保存在 RAM, 并成为ZOMBIE.
注: init 进程总是会执行 wait 系列函数去清除 ZOMBIE.

阅读(1774) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~