一文读懂Linux进程管理一(进程原理与分析)
一、进程原理
1.进程
Linux内核把进程称为任务(task),进程的虚拟地址空间分为用户虚拟地址空间和内核虚拟地址空间,所有进程共享内核虚拟地址空间,每个进程有独立的用户虚拟地址空间。
进程有两种特殊形式:没有用户虚拟地址空间的进程成为内核线程,共享用户虚拟地址空间的进程称为用户线程。通用在不会引起混淆的情况下把用户线程简称为线程。共享同一用户虚拟地址空间的所有用户线程组成一个线程组。
C标准库的进程专业术语和Linux内核的进程专业术语对应关系如下:

2.Linux进程四要素
有一段程序供其执行
有进程专用的系统堆栈空间
在内核有task_struct数据结构
有独立的存储空间,拥有专有的用户空间
如果只具备前三条缺少第四条,称为:线程 如果完全没有用户空间,称为:内核线程 如果共享用户空间映射,称为:用户线程
内核为每个进程分配一个task_struct结构时,实际分配两个连续的物理页面(8192字节),数据结构task_struct的大小约占1kb字节左右,进程的系统空间堆栈的大小约为7kb字节(不能扩展,是静态确定的)
3.进程描述符task_struct数据结构内核源码,其主要核心成员如下

【文章福利】小编推荐自己的Linux内核技术交流群:【891587639】整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!!!(含视频教程、电子书、实战项目及代码)


4.创建新进程
在Linux内核中,新进程是从一个已经存在的进程复制出来的,内核使用静态数据结构造成0号内核线程,0号内核线程分叉生成1号内核线程和2号内核线程(kthreadd线程)。1号内核线程完成初始化以后装载用户程序,变成1号进程,其他进程都是1号进程或者它的子孙进程分叉生成的,其他内核线程时kthreadd线程分叉生成的。
3个系统调用用来创建新的进程:
fork(分叉):子进程是父进程的一个副本,采用定时复制技术。
vfork:用于创建子进程,之后子进程立即调用execve以装载新程序的情况,为了避免复制物理页,父进程会睡眠灯带子进程装载新程序。现在fork采用了定时复制技术,vfork失去了速度优势,已被废弃。
clone(克隆):可以精确的控制子进程和父进程共享那些资源,这个系统调用的主要用处是可供pthread库来床架线程。clone是功能最齐全的的函数,参数多使用复杂,fork是clone的简化函数。
Linux内核定义系统调用的独特方式,目前以系统调用fork为例,fork调用_do_fork为例,流程如下:

在调用_do_fork的过程中,主要是cory_process

同一个线程组的所有线程必须属于相同的用户命名空间和进程号命名空间。
二、进程状态迁移
进程主要有7种状态:
就绪状态
运行状态
轻度睡眠
中度睡眠
深度睡眠
僵尸状态
死亡状态
状态变迁如下:

三、进程调度策略和优先级
1.Linux内核支持调度策略
先进先出(SCHED_FIFO)、轮流调度(SCHED_RR)、限期调度策略(SCHED_DEADLINE)采用不同的调度策略调度实时进程
普通进程支持两种调度策略:标准轮流分时(SCHED_NORMAL)和SCHED_BATCH调用普通的非实时进程
空闲(SCHED_IDLE)则在系统空闲时调用idle进程

2.进程优先级
限期进程的优先级比实时进程高,实时进程比普通进程高
限期进程的优先级是-1
实时进程的实时优先级是1-99,优先级数值越大,表示优先级越高
普通进程的静态优先级是100-139,优先级值越小,表示优先级越高,可通过修改nice值改变普通进程的优先级,优先级等于120加上nice值。
在task_struct结构体中,4个成员的优先级有关如下:


四、写时复制
写时复制核心思想:只有在不得不复制数据内容时采取复制数据内容

