进程状态和进程优先级

目录

1.进程状态

1.1Linux内核源代码怎么说

1.2进程状态查看

1.3Z(zombie)-僵⼫进程

1.4僵⼫进程危害

1.5孤⼉进程

1.5.1如何结束孤儿进程

2.进程优先级

2.1基本概念

2.2查看系统进程

[2.3PRI(Priority进程优先级)和 NI(Nice进程谦让值)](#2.3PRI(Priority进程优先级)和 NI(Nice进程谦让值))

[2.4查看 / 修改进程优先级的命令](#2.4查看 / 修改进程优先级的命令)

2.5竞争、独⽴、并⾏、并发


1.进程状态

1.1Linux内核源代码怎么说

  • 为了弄明⽩正在运⾏的进程是什么意思,我们需要知道进程的不同状态。⼀个进程可以有⼏个状 态(在Linux内核⾥,进程有时候也叫做任务)。 下⾯的状态在kernel源代码⾥定义:
cpp 复制代码
/*
*The task state array is a strange "bitmap" of
*reasons to sleep. Thus "running" is zero, and
*you can test for combinations of others with
*simple bit tests.
*/
static const char *const task_state_array[] = {
 "R (running)", /*0 */
 "S (sleeping)", /*1 */
 "D (disk sleep)", /*2 */
 "T (stopped)", /*4 */
 "t (tracing stop)", /*8 */
 "X (dead)", /*16 */
 "Z (zombie)", /*32 */
};
  • R运⾏状态(running):并不意味着进程⼀定在运⾏中,它表明进程要么是在运⾏中要么在运⾏队列⾥。
  • S睡眠状态(sleeping):意味着进程在等待事件完成(这⾥的睡眠有时候也叫做可中断睡眠 (interruptible sleep))。
  • D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个 状态的进程通常会等待IO的结束。
  • T停⽌状态(stopped):可以通过发送 SIGSTOP 信号给进程来停⽌(T)进程。这个被暂停的 进程可以通过发送 SIGCONT 信号让进程继续运⾏。
  • X死亡状态(dead):这个状态只是⼀个返回状态,你不会在任务列表⾥看到这个状态。
  • 运行:即进程在调度队列中,进程的状态都是running!
  • 阻塞:等待某种设备或者资源就绪(键盘,显示器,网卡,磁盘,摄像头,话筒...)
  • OS要管理系统种的各种硬件资源,先描述,再组织!因此,进程状态的变化,表现之一,就是要在不同的队列中进行流动。本质都是数据结构的增删查改。

1.2进程状态查看

  • ps aux / ps axj 命令
  • ps ajx | head -1 && ps ajx | grep 关键字 打印表头并过滤想要的信息(grep -v反向过滤)
  • while :; do ps ajx | head -1 && ps ajx | grep myprocess;sleep 1; done(1秒查一次)
  • a:显⽰⼀个终端所有的进程,包括其他⽤⼾的进程。
  • x:显⽰没有控制终端的进程,例如后台运⾏的守护进程。
  • j:显⽰进程归属的进程组ID、会话ID、⽗进程ID,以及与作业控制相关的信息
  • u:以⽤⼾为中⼼的格式显⽰进程信息,提供进程的详细信息,如⽤⼾、CPU和内存使⽤情况等

1.3Z(zombie)-僵⼫进程

  • 僵死状态(Zombies)是⼀个⽐较特殊的状态。当进程退出并且⽗进程(使⽤wait()系统调⽤,后⾯讲)没有读取到⼦进程退出的返回代码时就会产⽣僵死(⼫)进程
  • 僵死进程会以终⽌状态保持在进程表中,并且会⼀直在等待⽗进程读取退出状态代码。
  • 所以,只要⼦进程退出,⽗进程还在运⾏,但⽗进程没有读取⼦进程状态,⼦进程进⼊Z状态

总结产生僵尸进程的原因:子进程已经退出,但父进程没调用 wait () 读取它的退出状态,导致子进程的进程描述符还留在系统进程表里,这种状态就是僵尸进程,标识为 Z。

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

int main() {
    // 创建子进程
    pid_t id = fork();

    if (id < 0) {
        // fork 失败
        perror("fork");
        return 1;
    } 
    else if (id > 0) {
        // 父进程逻辑:睡眠30秒,期间不处理子进程退出状态
        printf("parent[%d] is sleeping...\n", getpid());
        sleep(30);
    } 
    else {
        // 子进程逻辑:睡眠5秒后退出,成为僵尸进程
        printf("child[%d] is begin Z...\n", getpid());
        sleep(5);
        exit(EXIT_SUCCESS);
    }

    return 0;
}

上述代码子进程5秒后退出,但父进程没使用wait()

我们可是在父进程部分的代码增加:

cpp 复制代码
int status;
wait(&status);

wait(&status) 调用后,父进程会立即进入阻塞状态,直到有子进程退出,然后内核会回收这个子进程的资源(避免僵尸),并把退出状态写入 status,之后父进程才会继续执行后续代码。

1.4僵⼫进程危害

  • 进程的退出状态必须被维持下去,因为他要告诉关⼼它的进程(⽗进程),你交给我的任务,我办的怎么样了。可⽗进程如果⼀直不读取,那⼦进程就⼀直处于Z状态?------是的!
  • 维护退出状态本⾝就是要⽤数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中, 换句话说,Z状态⼀直不退出,PCB⼀直都要维护?------是的!
  • 那⼀个⽗进程创建了很多⼦进程,就是不回收,是不是就会造成内存资源的浪费?------是的!因为数 据结构对象本⾝就要占⽤内存,想想C中定义⼀个结构体变量(对象),是要在内存的某个位置 进⾏开辟空间!
  • 内存泄漏?------是的!

1.5孤⼉进程

  • ⽗进程如果提前退出,那么⼦进程后退出,进⼊Z之后,那该如何处理呢?
  • ⽗进程先退出,⼦进程就称之为"孤⼉进程"
  • 孤⼉进程被1号init进程领养,当然要有init进程回收喽。
  • 孤儿进程会被1号进程(通常是initsystemd)接管并回收,以避免资源泄漏。
cpp 复制代码
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>  // 补充pid_t类型的头文件,避免编译警告

int main() {
    // 创建子进程
    pid_t id = fork();

    // 检查fork是否失败
    if (id < 0) {
        perror("fork");
        return 1;
    }
    // 子进程逻辑
    else if (id == 0) {
        printf("I am child, pid : %d\n", getpid());
        sleep(10);  // 子进程睡眠10秒
    }
    // 父进程逻辑
    else {
        printf("I am parent, pid: %d\n", getpid());
        sleep(3);   // 父进程睡眠3秒后退出
        exit(0);
    }

    return 0;
}

1.5.1如何结束孤儿进程

如下,我们看见父进程退出后孤儿进程无法用 Ctrl+C 结束,因为Ctrl+C 发送的 SIGINT 信号仅作用于终端前台进程组,父进程退出后,孤儿进程被 1 号进程接管并脱离原前台进程组,进入后台,因此收不到该信号,无法响应 Ctrl+C。

我们可以使用kill指令结束孤儿进程

kill -9 进程号

2.进程优先级

2.1基本概念

  • cpu资源分配的先后顺序,就是指进程的优先权(priority)。
  • 优先权⾼的进程有优先执⾏权利。配置进程优先权对多任务环境的linux很有⽤,可以改善系统性 能。
  • 还可以把进程运⾏到指定的CPU上,这样⼀来,把不重要的进程安排到某个CPU,可以⼤ 改善 系统整体性能。

总结:

是什么?

是进程得到CPU资源的先后顺序

为什么?

目标资源稀缺,导致通过优先级确认谁先谁后的问题!

怎么办?

优先级在linux中也是一种数字,int,task_struct

值越低,优先级越高,反之,优先级越低

基于时间片的分时操作系统,考虑公平性,优先级可能变化,但是变化幅度不能太大

优先级vs权限

优先级:能得到资源,先后的问题。

权限:是都能得到某种资源。

2.2查看系统进程

在linux或者unix系统中,⽤ps‒l命令则会类似输出以下⼏个内容:

我们很容易注意到其中的⼏个重要信息,有下:

  • UID: 代表执⾏者的⾝份
  • PID: 代表这个进程的代号
  • PPID:代表这个进程是由哪个进程发展衍⽣⽽来的,亦即⽗进程的代号
  • PRI:代表这个进程可被执⾏的优先级,其值越⼩越早被执⾏
  • NI:代表这个进程的nice值

ls -n:用数字 UID/GID 代替用户名 / 组名

所以Linux系统通过比对当前用户的UID与文件权限设置,来判断用户是否具备操作该文件的权限。

2.3PRI(Priority进程优先级 )和 NI(Nice进程谦让值

  • PRI也还是⽐较好理解的,即进程的优先级,或者通俗点说就是程序被CPU执⾏的先后顺序,此 值越⼩进程的优先级别越⾼
  • 那NI呢?就是我们所要说的nice值了,其表⽰进程可被执⾏的优先级的修正数值
  • PRI值越⼩越快被执⾏,那么加⼊nice值后,将会使得PRI变为:PRI(new)=PRI(old)+nice
  • 这样,当nice值为负值的时候,那么该程序将会优先级值将变⼩,即其优先级会变⾼,则其越快 被执⾏
  • 所以,调整进程优先级,在Linux下,就是调整进程nice值
  • nice其取值范围是-20⾄19,⼀共40个级别。
  • PRI:进程的优先级,默认:80
  • NI:进程优先级的修正数据,又称nice值
  • 进程真实的优先级=默认PRI值(80)+ NI

2.4查看 / 修改进程优先级的命令

修改进程优先级:

  • 使用top指令后按"r"‒>输⼊进程PID‒>输⼊nice值
  • 其他调整优先级的命令:nice,renice
  • 系统函数:

查看进程优先级:

ps -al | head -1 && ps -al | grep 进程名

2.5竞争、独⽴、并⾏、并发

  • 竞争性: 系统进程数⽬众多,⽽CPU资源只有少量,甚⾄1个,所以进程之间是具有竞争属性的。为 了⾼效完成任务,更合理竞争相关资源,便具有了优先级
  • 独⽴性: 多进程运⾏,需要独享各种资源,多进程运⾏期间互不⼲扰
  • 并⾏: 多个进程在多个CPU下分别,同时进⾏运⾏,这称之为并⾏(比如有两个CPU,两个进程在不同CPU上同时运行,这两个进程称之为并行)
  • 并发: 多个进程在⼀个CPU下采⽤进程切换的⽅式,在⼀段时间之内,让多个进程都得以推进,称之为并发(多个进程共享同一个CPU资源)
相关推荐
安科士andxe2 小时前
深入解析|安科士1.25G CWDM SFP光模块核心技术,破解中长距离传输痛点
服务器·网络·5g
小白同学_C5 小时前
Lab4-Lab: traps && MIT6.1810操作系统工程【持续更新】 _
linux·c/c++·操作系统os
今天只学一颗糖5 小时前
1、《深入理解计算机系统》--计算机系统介绍
linux·笔记·学习·系统架构
2601_949146535 小时前
Shell语音通知接口使用指南:运维自动化中的语音告警集成方案
运维·自动化
儒雅的晴天6 小时前
大模型幻觉问题
运维·服务器
Gofarlic_OMS7 小时前
科学计算领域MATLAB许可证管理工具对比推荐
运维·开发语言·算法·matlab·自动化
通信大师7 小时前
深度解析PCC策略计费控制:核心网产品与应用价值
运维·服务器·网络·5g
dixiuapp7 小时前
智能工单系统如何选,实现自动化与预测性维护
运维·自动化
不做无法实现的梦~7 小时前
ros2实现路径规划---nav2部分
linux·stm32·嵌入式硬件·机器人·自动驾驶
Elastic 中国社区官方博客7 小时前
如何防御你的 RAG 系统免受上下文投毒攻击
大数据·运维·人工智能·elasticsearch·搜索引擎·ai·全文检索