• Linux - 进程管理


    进程介绍

    进程(Process)是计算机中已运行程序的实体,是程序的一个具体实现。每个 Linux 进程在被创建的时候,都被分配给一段内存空间,即系统给该进程分配一定的逻辑地址空间。

    每个程序都能看到一片完整连续的地址空间,这些空间并没有直接关联到物理内存,而是操作系统提供了内存的一种抽象概念,使得每个进程都有一个连续完整的地址空间,在程序的运行过程,再完成虚拟地址到物理地址的转换。我们同样知道,进程的地址空间是分段的,存在所谓的数据段,代码段,bbs段,堆,栈等等。
    在这里插入图片描述

    进程的生命周期

    每个进程都有一个唯一的进程 ID (PID),用于追踪该进程。

    任何进程都可以通过复制自己地址空间的方式(fork)创建子进程,子进程中记录着父进程的 ID(PPID)。第一个系统进程是 systemd,其他所有进程都是其后代。

    • 每个进程都有自己生命周期,比如创建、执行、终止和删除。在系统运行过程中,这些阶段反复执行成千上万次
    • 当一个进程创建一个新的进程,创建进程的进程(父进程)使用名为fork()的系统调用。当fork()被调用的时候,它会为新创建的进程(子进程)获得一个进程描述符,并且设置新的进程ID。复制父进程的进程描述符给子进程。这时候,不会复制父进程的地址空间,而是父子进程使用同样的地址空间。
    • exec()系统调用把新程序复制到子进程的地址空间。由于共享同样的地址空间,写入新进程的数据会引发页错误的异常。此时,内核给子进程分配新的物理页。
    • 这个延迟的操作叫做Copy On Write。子进程和父进程执行的程序通常不一样,它执行自己的程序。这个操作避免了不必要的开销,因为,复制整个地址空间是很慢且低效率的,还会消耗很多的处理器时间和资源。
    • 当程序执行完成,子进程使用exit()系统调用终止。exit()会释放进程的大部分数据结构,并且把这个终止的消息通知给父进程。这时候,子进程被称为zombie process(僵尸进程)。
    • 直到父进程通过wait()系统调用知悉子进程终止之前,子进程都不会被完全的清除。一旦父进程知道子进程终止,它会清除子进程的所有数据结构和进程描述符。

    在这里插入图片描述

    进程的状态

    在这里插入图片描述

    • 运行状态(TASK_RUNNING):是运行态和就绪态的合并,表示进程正在运行或准备运行,Linux 中使用TASK_RUNNING 宏表示此状态
    • 可中断睡眠状态(浅度睡眠)(TASK_INTERRUPTIBLE):进程正在睡眠(被阻塞),等待资源到来是唤醒,也可以通过其他进程信号或时钟中断唤醒,进入运行队列。Linux 使用TASK_INTERRUPTIBLE 宏表示此状态。
    • 不可中断睡眠状态(深度睡眠状态)(TASK_UNINTERRUPTIBLE):其和浅度睡眠基本类似,但有一点就是不可被其他进程信号或时钟中断唤醒。Linux 使用TASK_UNINTERRUPTIBLE 宏表示此状态。
    • 暂停状态(TASK_STOPPED):进程暂停执行接受某种处理。如正在接受调试的进程处于这种状态,Linux 使用TASK_STOPPED 宏表示此状态。
    • 僵死状态(TASK_ZOMBIE):进程已经结束但未释放PCB,Linux 使用TASK_ZOMBIE 宏表示此状态。

    进程的优先级

    进程的 CPU 资源(时间片)分配就是指进程的优先级(priority);优先级高的进程有优先执行权利;配置进程的优先级对多任务环境下的 Linux 很有用,可以改善系统性能。

    使用 ps 命令查看进程
    在这里插入图片描述

    openEuler 中使用 CFS 调度器来调度进程

    • UID : 代表执行者的身份
    • PID : 代表这个进程的代号
    • PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
    • PRI :代表这个进程可被执行的优先级,其值越小越早被执行
    • NI :代表这个进程的nice值
    • 进程优先级由动态优先级(PRI)和静态优先级(PR)决定,它是决定进程在CPU中执行顺序的数字。优先级越高的进程被处理器执行的机会越大
    • 根据进程的行为,内核使用启发式算法决定开启或关闭动态优先级。可以通过nice级别直接修改进程的静态优先级,拥有越高静态优先级的进程会获得更长的时间片(时间片是进程在处理器中的执行时间)
    • Linux支持的nice级别从19(最低优先级)到-20(最高优先级),默认只是0。只有root身份的用户才能把进程的nice级别调整为负数(让其具备较高优先级)

    PRI,即进程的优先级,表示程序被CPU执行的先后顺序,值越小进程的优先级别越高;NI,即 nice 值 ,表示进程可被执行的优先级的修正数值,可理解为“谦让度”;进程的 nice 值不是进程的优先级,但是可以通过调整 nice 值可以影响进程的优先值。

    PRI 值越小越快被执行,那么加入nice值后,PRI变为:PRI(new)=PRI(old)+nice
    当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行
    内核使用一些简单的数值范围0~139表示内部优先级, 数值越低, 优先级越高。从0~99的范围专供实时进程使用, nice的值[-20,19]则映射到范围100~139
    在这里插入图片描述
    在这里插入图片描述

    调整进程的优先级

    openEuler 中使用 nice 和 renice 调整进程的 nice 值,进而影响进程优先级
    nice 命令语法,优先序(adjustment 取值范围 -19 ~ 20):

    nice [-n adjustment][command][arg...]]
    
    • 1

    例如,将 vi 运行的优先级设置为 -18:

    nice -n -18 vi &
    
    • 1

    renice 命令语法,优先序范围同 nice,作用对象有程序群组 -g、进程 -p、用户-u,语法格式:

    renice [-n adjustment][-]<pid>
    
    • 1

    例如,将 vi 运行的优先级设置为 10:

    # renice -n 12 -p 9700
    9700(process ID) old priority -18, new priority 12
    
    • 1
    • 2

    查看 nice 说明:nice –help
    查看 renice 说明:renice –h

    也可以使用 top 更改进程的 NI 值:
    进入top后按“r”–>输入进程PID–>输入nice值

    前台与后台进程

    后台进程几乎不和用户交互,优先级略低。Linux 的守护进程(Daemon)是一种特殊的后台进程,其独立于终端并周期性地执行任务或等待唤醒。

    前台进程和用户交互,需要较高的响应速度,优先级较高。前台进程就是用户使用的有控制终端的进程。

    • 守护的意思就是不受终端控制。
    • Linux的大多数服务器就是用守护进程实现的。比如,Internet服务器inetd,Web服务器httpd等。同时,守护进程完成许多系统任务。比如,作业规划进程crond,打印进程lpd等
    • 守护进程一般用作系统服务,可以用crontab提交,编辑或者删除相应得作业。
    • Daemon进程也就是守护进程,linux大多数的服务进程都是通过守护进程实现的。比如0号进程(调度进程) ,1号进程(init进程)。机器启动后就运行,关机才停止。

    控制前台与后台进程

    opneEuler 中常用以下命令管理进程,包括前后台切换及启停:

    • &:将 & 放在命令的最后,可以把这个命令放到后台执行
    • Ctrl + z:当前台正在执行一个命令时,按键 Ctrl + z,将其放到后台并暂停
    • Ctrl + c:中断当前正在执行的命令
    • jobs:查看当前有多少正在后台运行的命令
    • fg:将后台中的命令调至前台继续运行
    • bg:将后台任务唤醒,并在后台运行

    查看进程

    使用ps或top命令查看每个进程的详细信息。

    ps 命令可以显示当前进程,并列出详细的进程信息,字段含义如下表。常用 ps auxps -ef 查看进程信息。

    ps 命令用于显示特定时间点的进程信息,top 命令可以实时显示进程信息。

    在这里插入图片描述

    管理进程 - 信号

    openEuler 中,进程之间通过信号来通信,常见信号见表格。
    在这里插入图片描述

    进程的信号是预定义好的一个消息,进程能识别它并决定是忽略还是做出反应。系统管理员需要知道如何向一个进程发送何种信号,以管理进程。

    管理进程

    openEuler 中使用 kill 和 killall 命令向进程发送信号;发送的前提是,当前用户必须是进程的属主或 root 用户;kill 通过 PID 向进程发信号,默认发送 TERM 信号,使用 –s 参数指定其他信号,例:

    # kill 3389
    # kill -s HUP 3389
    
    • 1
    • 2

    killall 通过进程名向进程发信号,且支持通配符,例:

    killall python*
    
    • 1
  • 相关阅读:
    word页脚设置,页脚显示第几页共有几页设置步骤
    std::decay 源码分析
    好用的办公网优化工具OneDNS
    力扣leetcode 667. 优美的排列 II
    2020年MathorCup数学建模D题新零售目标产品的精准需求预测解题全过程文档加程序
    js---构造函数
    基于JSP动漫论坛的设计与实现
    【7.28】代码源 - 【Fence Painting】【合适数对(数据加强版)】
    nodejs-express项目初始化
    供应商寄售过程的实现
  • 原文地址:https://blog.csdn.net/qq_51601649/article/details/126001033