《Linux操作系统原理分析之Linux 进程管理 1》(5)
- 4 Linux 进程管理
- 4.1 Linux 进程概述
- 4.1.1 Linux 进程的组成
- 4.1.2 Linux 进程在处理机上的执行状态
- 4.1.3 进程空间和系统空间
- 4.1.4 进程上下文和系统上下文
4 Linux 进程管理
4.1 Linux 进程概述
4.1.1 Linux 进程的组成
1.Linux 进程组成:由 正文段(text)、用户数据段(user segment)和系统数据段。
正文段
:存放进程要执行的指令代码。Linux 中正文段具有只读属性。
用户数据段
:进程运行过程中处理数据的集合,它们是进程直接进行操作的所有数据,包括进程运行处理的数据段和进程使用的堆栈。
系统数据段
:存放反映一个进程的状态和运行环境的所有数据。这些数据只能由内核访问和使用。 在系统数据段中包括进程控制块 PCB.。
在 Linux 中,PCB 是一个名为 task_struct 的结构体,称为任务结构体 称为任务结构体
。
2.任务结构体的主要内容
任务结构体 task_struct 的大小约 1000B。它定义在源代码的 include/linux/sched.h 下。下面把它的成员
的功能和作用归纳为 9 个方面予以说明:
序号 | 功能 | 说明 |
---|---|---|
1) | 进程的状态和标志 | state 和 flags。 |
2) | 进程的标识。 | 表示进程标识的成员项:pid,uid,gid 等。 |
3) | 进程的族亲关系 | p_opptr、p_pptr、p_cptr、p_vsptr、p_osptr |
4) | 进程间的链接信息。 | Next_task、prev_task、next_run、prev_run。 |
5) | 进程的调度信息。 | Counter、priority、rt_priotity、policy。 |
6) | 进程的时间信息。 | 表示系统中各种时间成员项:start_time、utime、stime、cutime、cstime、timeout。 表示定时器的成员项:it_real_value、it_real_incr、it_virt_value、it_virt_ incr、it_prof_value、it_prof_ incr、real_timer。 |
7) | 进程的虚拟信息。 | Mm、ldt、saved_kernel_stack、kernel_stack_page。 |
8) | 进程的文件信息 | Fs、file。 |
9) | 与进程通信有关的信息 | singnal、blocked、sig、exit_signal、semundo、semsleeping。 |
3.任务结构体的管理
- task[]数组
为了管理系统中所有进程,系统在内核空间设置了一个指针数组 task[],该数组的每一个元素指向一个任务结构体,所以 task 数组又称 task 向量。
Task 数组的大小决定了系统中容纳进程最大数量。在 linux 内核源代码 kernel/sched.c 中 task 数组的定义如下:
Struct task_struct *task[NR_TASKS]={&init_task};
可以看到:
👉task[]数组是一个指向 task_struct 结构的指针数组。
👉其中符号常量 NR_TASKS 决定了数组的,/include/linux/task.h 中,它的默认值被定义为512:#define NR_TASKS 512
👉 task[]数组的第一个指针指向一个名字为 init_task 的结构体,它是系统初始化进程 init 的任务结构体。
2)nr_tasks
为了记录系统中实际存在的进程数,系统定义了一个全局变量 nr_tasks,其值随系统中存在的进程数目而变化。在 kernel/fork.c 中,它的定义及初始化如下:
Int nr_tasks =1;
3)双向循环链表
Linux 中把所有进程的任务结构相互连成一个双向循环链表,其首结点就是 init 的任务结构体init_task。这个双向链表是通过任务结构体中的两个成员项指针相互链接而成:
Struct task_struct *next_task;/*指向后一个任务结构体的指针*/
Struct task_struct *prev_task;/*指向前一个任务结构体的指针*/
宏定义:
SET_LINKS:插入一个任务结构体
REMOVE_LINKS:删除一个任务结构体
For_each_task:遍历所有任务结构体
4.1.2 Linux 进程在处理机上的执行状态
在 Linux 系统中,用户不能直接访问系统资源,如处理机、寄存器、存储器和各种外围设备。因此提供了两种不同指令
:
一般指令
:供用户和系统编程使用,不能直接访问系统资源;
特权指令
:供操作系统使用,可以直接访问和控制系统资源;
为了区分处理机在执行那种指令,通常将处理机的执行状态
又分为两种:
管态
(内核态、系统)
目态
(用户态)
由目态转变为管态的情况可能有:
1、进程通过系统调用向系统提出服务请求
2、进程执行某些不正常的操作时,如除数为 0、超出权限的非法访问、用户堆栈溢出等。
3、进程使用设备进行 I/O 操作时,当操作完成或设备出现异常情况时。
4.1.3 进程空间和系统空间
进程的虚拟地址空间:Linux 操作系统运行在多道环境下,多个进程能够同时在系统中并发活动。为了防止进程间的干扰,系统为每个进程都分配了一个相对独立的虚拟地址空间,又称为进程的虚拟内存空间。
进程的虚拟地址空间包含进程本身的代码和数据等,同时还包括操作系统的代码和数据。故进程的虚拟地址空间分两部分:进程空间和系统空间。
进程空间:
👉内核堆栈:进程在需要使用内核功能而通过系统调用运行内核代码时,需要使用堆栈保存数据。这个堆栈是由系统内和使用的,故称内核堆栈。
👉其中系统数据段,只能在内核态执行
系统空间:操作系统的内核映射到进程的虚拟地址空间。(可供多个进程共享,只能内核态执行)
4.1.4 进程上下文和系统上下文
进程上下文:进程的运行环境动态变化,在 linux 中把进程的动态变化的环境总和称为进程上下文。
👉当前进程
👉 进程切换
👉 上下文切换
👉进程通过系统调用执行内核代码时,内核运行是为进程服务,所以此时内核运行在进程上下文中。
系统上下文
:内核除了为进程服务,也需要完成操作系统本身任务,如响应外部设备的中断、更新有关定时器、重新计算进程优先级等。 故把系统在完成自身任务时的运行环境称为系统上下文(system context).