Linux进程控制介绍

目录

1.  进程的定义

2.  进程的控制模块

3.  进程的创建

4.  进程状态

5.  进程调度


1.  进程的定义

        进程是处于执行期的程序,但进程并不仅仅局限于一段可执行程序代码,通常还包括其他资源,如打开的文件、挂起的信号、内核内部数据、处理器状态、地址空间以及一个或者多个执行线程、用来存放全局变量的数据段等。

        进程是一个程序的一次执行的过程,同时也是资源分配的最小单位。它和程序是有本反区别的:程序是静态的,是一些保存在磁盘上的指令的有序集合,没有任何执行的概念;而进程是一个动态的概念,它是程序执行的过程,包括动态创建、调度和消亡的整个过程。进程是程序执行和资源管理的最小单位。因此,对系统而言,当用户在系统中输入命令执行一个程序时,它将启动一个进程。

        程序本身不是进程,进程是处于执行期的程序以及它所包含的资源的总称。实际上完全可能存在两个不同的进程执行的是同一个程序,并且两个或两个以上并存的进程还可以共享许多如打开文件、地址空间之类的资源。

        在Linux系统中,进程分为用户进程、守护进程、批处理进程:

  • 用户进程:也成终端进程,用户通过终端命令启用的进程。
  • 守护进程:也成精灵进程,即运行的守护进程,在系统引导时间就启动,是后台服务进程,大多数服务进程都是通过守护进程实现的。
  • 批处理进程:执行的是批处理文件、shell脚本。
     

2.  进程的控制模块

        进程控制模块(Process Control Module) 是内核的核心组件之一,负责进程的创建、终止、状态转换、调度及资源管理等全生命周期操作。它通过操控进程控制块(如 Linux 的task_struct)实现对进程的管理,是多任务操作系统实现并发执行的基础。

        对于 task_struct 文件,可以通过如下路径获取内核源码:

The Linux Kernel Archives

        通常存放在 include/linux/sched.h 路径下:

        也可以直接通过在线工具,在线查看:

sched.h - include/linux/sched.h - Linux source code v6.17.1 - Bootlin Elixir Cross Referencer

        这里如果不知道自己Linux内核是多少的可以通过如下命令查看:

uname -r

        其中6代表主版本号、8代表次版本号、0代表修订号、85代表发行版本号、后面为发行版本标识generic标识通用版本:

3.  进程的创建

        内核通过一个唯一的进程标识值PID标识每个进程。PID是一个int型数,其代表系统中允许同时存在的最大数目。

        一个进程要被执行,首先要被创建,进程需要一定的系统资源,如CPU时间片、内存空间、操作文件、硬件设备等,进程创建包括如下操作:

  • 初始化当前进程PCB(进程控制模块),分别配有效进程 ID,设置进程优先级和CP时间片
  • 为进程分配内存空间
  • 加载任务到内存空间,将进程代码复制到内存空间
  • 设置进程执行状态为就绪态,将进程PCB放入到进程队列中

        操作系统内核为方便所有进程进行管理,将进程的PCB放在队列中,新创建的进程放入队尾,当进程执行完毕后,从队列中踢除,Linux系统中有两个重要的队列:

  • 运行队列:内核要寻找一个新的进程在CPU上运行,必须考虑处于可运行状态的进程,不过扫描整个进程链表是相对低效的,所以引入了可运行状态进程的双向循环链表,也叫运行队列。
  • 等待队列:处于睡眠状态的进程被放入等待队列当中,等待队列是以双循环列表为基础的数据结构,与进程调度机制紧密结合,能够用于实现核心的异步时间通知机制。

4.  进程状态

        Linux 内核在task_struct结构体中通过state字段定义进程状态,核心状态包括:

状态名称宏定义(内核中)含义与特点
运行态TASK_RUNNING进程要么正在 CPU 上执行,要么在就绪队列等待调度。新进程通过fork()创建后进入此状态;处于可中断 / 不可中断睡眠态的进程,等待的事件发生后会被唤醒回到该状态;停止态的进程 “继续” 后也会回到运行态;还可能被更高优先级进程抢占后暂时离开运行态。
可中断睡眠态TASK_INTERRUPTIBLE进程因等待资源(如 I/O、信号量)而暂停,可被信号唤醒(转为就绪态)。
不可中断睡眠态TASK_UNINTERRUPTIBLE进程因等待关键资源(如磁盘 I/O)而暂停,不可被信号唤醒(确保资源操作原子性)。
暂停态TASK_STOPPED进程被暂停执行(如收到SIGSTOPSIGTSTP信号),需SIGCONT信号恢复。
销毁态TASK_DEAD父进程处理完僵尸进程后,进程最终进入销毁态,相关资源被彻底释放。。
僵尸态EXIT_ZOMBIE进程已终止,但父进程未调用wait()系列函数回收其 PCB(保留 PID 和退出状态)。

5.  进程调度

        就绪队列(Ready Queue),存储所有处于就绪状态的进程,等待被调度执行。当一个进程被创建、从阻塞状态变为就绪状态,或者从运行状态被暂停时,它会被放入就绪队列。

        上下文切换(Context Switch),当调度器选择一个新的进程执行时,需要保存当前正在运行进程的上下文(包括 CPU 寄存器的值、程序计数器、栈指针等),并加载新进程的上下文,这个过程就是上下文切换。上下文切换会带来一定的开销,因此高效的调度算法会尽量减少不必要的上下文切换。

        进程的调度方法,根据不同的使用场景有多种:

  • 先来先服务(First-Come, First-Served,FCFS):按照进程进入就绪队列的先后顺序进行调度,先进入的进程优先获得 CPU 资源。该算法简单易实现,但对于短进程来说可能不太公平,因为长进程可能会占用 CPU 很长时间,导致短进程等待时间过长。例如,有进程 A(运行时间 10ms)和进程 B(运行时间 1ms),若 A 先进入就绪队列,B 需要等待 A 执行完才能执行,B 的等待时间就会较长。
  • 短作业优先(Shortest Job First,SJF):从就绪队列中选择预计运行时间最短的进程进行调度。可以分为非抢占式和抢占式(最短剩余时间优先,SRTF)。SJF 能有效减少平均周转时间,但缺点是难以准确预知进程的运行时间,并且可能导致长进程饥饿(长时间得不到调度)。
  • 时间片轮转(Round Robin,RR):每个进程被分配一个时间片(如 100ms),在时间片内进程可以占用 CPU 运行。当时间片用完后,即使进程没有执行完毕,也会被暂停并放入就绪队列末尾,等待下一次调度。RR 算法能较好地保证系统的响应时间,适用于分时系统,让多个交互型用户感觉系统在同时为他们服务。
  • 优先级调度(Priority Scheduling):为每个进程分配一个优先级,调度器总是选择优先级最高的进程执行。优先级可以根据进程的类型(如系统进程优先级通常较高)、重要程度等因素来确定。该算法可能导致低优先级进程饥饿,因此可以采用动态优先级调整的方式,例如随着等待时间增加,进程优先级逐渐提高。
  • 多级反馈队列(Multilevel Feedback Queue):将进程按优先级划分为多个队列,每个队列对应不同的时间片(优先级越高,时间片越短)。新进程首先进入最高优先级队列,获得一个较短的时间片。如果在时间片内没有执行完,就会被移到下一级队列,获得更长的时间片。多级反馈队列算法综合了多种调度算法的优点,能较好地适应不同类型的进程。

        在 Linux 操作系统中,采用了完全公平调度器(Completely Fair Scheduler,CFS)作为默认的进程调度器。CFS 基于进程的虚拟运行时间(vruntime)来进行调度,它为每个进程维护一个虚拟运行时间,每次调度时选择虚拟运行时间最短的进程执行,从而实现了公平性。

嵌入式Linux_时光の尘的博客-优快云博客

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时光の尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值