【深入浅出】Linux进程(三)

在这里插入图片描述

📃博客主页: 小镇敲码人
💚代码仓库,欢迎访问
🚀 欢迎关注:👍点赞 👂🏽留言 😍收藏
🌏 任尔江湖满血骨,我自踏雪寻梅香。 万千浮云遮碧月,独傲天下百坚强。 男儿应有龙腾志,盖世一意转洪荒。 莫使此生无痕度,终归人间一捧黄。🍎🍎🍎
❤️ 什么?你问我答案,少年你看,下一个十年又来了 💞 💞 💞


【深入浅出】Linux进程(三)

  • 进程的优先级(普通进程)
    • 进程优先级与权限问题
  • 进程的调度与切换
    • 相关概念介绍
  • 环境变量
    • main函数的参数
    • 环境变量

进程的优先级(普通进程)

  1. 进程优先级的定义

    内存中会同时存在多个exe文件,进而就会同时存在多个进程,这些进程可能会同时需要某个资源,比如CPU,他们需要依据进程优先级来排队,确定享受资源的先后顺序。进程优先级是操作系统的调度处理器时间给不同进程时所依据的一个数值或级别。这个值决定了进程在等待CPU时间片分配时的优先顺序和时间。优先级高的进程会比优先级低的进程更早获得CPU资源。

  2. 为什么需要进程优先级:因为资源是有限的!!!

  3. Linux中如何设置进程优先级?

    • task_struct结构体中有关于进程优先级的属性。

      image-20241110121151360

      • 用户通过设置nice值,来影响进程的优先级pri
    • Ubuntu24.04系统中,Linux中进程的默认优先级为20。我们通过设置进程的nice值,来影响它的PRI:

      • PRI = PRI(old)+nice值。这个PRI(old)是默认的优先级20。

      • 此时,我们允许进程main,它的默认PRI为20,nice值为0:

        image-20241110124238179

      • 我们通过renice指令,可以用来调整正在运行的进程的nice值,从而影响它的PRIrenice [新的nice值] -p [进程pid],我们将nice值设置为-10,按照计算公式,新的进程PRI = 20-10应该为10:

        image-20241110124527407

        • 和我们预期的一致。
      • nice值设置为10,新的进程PRI应该为PRI = 20+10= 30:

        image-20241110124732076

    • Linux中的nice极值测试,nice的范围[-20,19]:

      • 最小值(值越小,优先级越大):

        image-20241110124910516

        • 这里其实显示的内容有点问题,应该是old nice为10,new nice为-20,但是Linuxnice值和PRI值是可以换算的,这样说也问题不大,就是容易误导初学者。

        image-20241110125042252

      • 最大值(值越大,优先级越小):

        image-20241110125129801

        image-20241110125213500

    • Linux还有一些特殊进程的优先级,不在[0,39]的范围内:

      image-20241110125423831

      • 这些PRI为负数的进程为实时进程,为正数的是普通进程,这样可以更好的区分它们。我们学习的主要是普通进程,大多数用户进程和后台服务都属于普通进程。实时进程暂时不做介绍。

进程优先级与权限问题

  1. 普通用户是不能随意设置nice值。

    • 如果允许普通用户随意设置nice,它就可能会把属于自己的进程的优先级设置的很高,这样其它用户的进程就没办法享受到资源,就会造成饥饿问题。

    • 但是普通用户可以把nice值增大(默认是0),降低自己的进程优先级(不能增加):

      • 介绍一个新的指令nice,它主要可以在进程启动时设置它的nice值,nice -n [nice值]./可执行文件:

        image-20241110131254659

    • 如果降低nice值就会报错:

      image-20241110131630160

  2. 为什么Linux操作系统不允许直接设置PRI值。

    • nice值相对较小,而且直观,用户友好性好。
    • 如果允许用户直接设置PRI 值,可能会导致用户滥用高优先级进程,影响系统的整体性能和稳定性。通过 nice 值,系统可以限制普通用户只能增加进程的 nice 值(降低优先级),而不能减少 nice 值(提高优先级)。

进程的调度与切换

相关概念介绍

  1. 进程在运行的时候,放在CPU上,执行指令,并不是必须一次性把进程代码跑完,现代操作系统都是基于时间片进行轮转运行的。

    • 竞争性:系统中进程是有很多的,但是CPU只有一个,所以为了使用CPU,这些进程是竞争关系,也因此出现了优先级。
    • 独立性:多进程运行,需要独享资源,运行期间互不干扰。
    • 并行:多个进程在多个CPU下同时运行,这叫做并行。
    • 并发:多个进程在一个CPU下以进程切换的方式,在一段时间内,让多个进程都能运行,看起来好像是同时运行,这叫做并发。
  2. 进程切换:现代操作系统中,多个进程按照时间片轮转运行,当一个进程的运行时间到了,它就会被挂起,为了让它下一次运行能接着运行,我们会保存这个进程的相关数据,这个数据就是上下文数据。所以,进程切换的本质也就是上下文数据的切换。上下文数据,也就是CPU中的寄存器信息。

    image-20241110172807308

    • 寄存器和寄存器数据不是一个概念,每一个进程的寄存器数据都是私有的。
    • 所有的上下文数据保存都是为了下一次的恢复,所有的恢复都是为了能继续上一次pc位置的运行。
  3. 进程调度:

    • 进程调度算法:有很多不同的进程调度算法。

      • 实时调度器(Real-Time Schedulers)
        • SCHED_FIFO:实时优先级调度器,遵循 FIFO 原则。具有相同优先级的进程按到达顺序执行,高优先级进程总是优先于低优先级进程。
        • SCHED_RR:实时轮转调度器,类似于 SCHED_FIFO,但每个进程有一个固定的时间片,时间片结束后进程会被移到队列末尾。
      • 还有很多不同的调度策略,我们不再介绍,不管是怎么样的调度策略,一个优秀的调度算法,应该要考虑进程的优先级、进程的饥饿问题以及效率。
    • 进程调度队列(runqueue运行队列):

      59712d0b-592d-408c-8f09-741b01ca06db

      • 这个结构体中有两个关键的属性,就是活跃队列和过期队列。

      • 活跃队列:活跃队列存储当前就绪且可以运行的进程。调度器会从活跃队列中选择下一个要运行的进程。

      • 过期队列:过期队列存储已经用完其时间片但尚未完成的进程。

      • 协调机制:当活跃队列为空时,调度器会将过期队列中的进程重新放入活跃队列中,以便继续调度。活跃队列和过期队列交换,变为空队列,初始时,所有的就绪队列都会放进活跃队列中。

      • 活跃队列中存储的是进程描述符task_struct

      • 如何找到第一个非空活跃队列:通过位图,我们能快速筛选出非空队列,遍历一次就可以排除32个队列(如果bitmap[i]值为0),然后排除后,下次的队列下标就要加上32*i(i为排除了多少个32位)了,发现第一个不为32位的,最多遍历32次就可以找到如果bitmap[i] & (1 << j)不为0,就说明该位置队列不为空,开始调度。这是设计bitmap应该考虑的事情,这个数据结构会有相应的方法,判断某一位是否有值。

环境变量

在介绍Linux的环境变量前,我们先来介绍一下main函数的参数。

main函数的参数

是的,你没有看错,其实我们的main也有参数。

int main(void);
int main(int argc,char* argv[],char* env[])

这两种函数都可以用,argc是命令行会自动传的,它会传命令行的参数的个数,以空格为分隔符,argv存储我们的命令行参数,看下面的代码:

#include<stdio.h>

int main(int argc,char* argv[])
{
  for(int i = 0;i < argc;++i)
  {
   printf("%d: %s\n",i,argv[i]);
  }
  return 0;
}

运行结果:

image-20241110181919688

  • 连续的空格会被视作一个分隔符。另外,我们的main函数只写两个参数是可行的,因为存在这种main函数,实际上有三种main函数。

  • 传命令行参数给main有什么作用呢?我们可以通过不同的选项,让其执行同一程序的不同功能,这和我们的指令通过指定不同选项来实现不同功能的原理是一样的,所以命令行参数是Linux指令的基础。看下面的demo代码,使用命令行参数在同一程序中实现不同的选项执行不同的功能(加减乘):

    #include<stdio.h>
    #include <stdlib.h>
    #include<string.h>
    
    int main(int argc,char* argv[])
    {
      if(argc != 4)
      {
       printf("Usage: \n\r%s: -[add | sub | mul] x y\n\n",argv[0]);
       return 1;
      }
    
      int x = atoi(argv[2]);//将字符串转为整数
      int y = atoi(argv[3]);
    
      if(strcmp(argv[1],"-add") == 0)
      {
        printf("%d+%d=%d\n",x,y,x+y);
      }
    
      else if(strcmp(argv[1],"-sub") == 0)
      {
        printf("%d-%d=%d\n",x,y,x-y);
      }
    
      else if(strcmp(argv[1],"-mul") == 0)
      {
        printf("%d*%d=%d\n",x,y,x*y);
      }
    
      else
      {
       printf("Unknow!!!!\n");
      }
    
      return 0;
    }
    

    运行结果:

    image-20241110184321870

环境变量

  • 环境变量:就是Linux系统内置的有特殊用途的变量,定义变量的本质是程序运行时在内存中开辟空间,然后把相应的内容写入这段空间中,操作系统/bash是用C语言写的程序,它也可以在运行中开辟空间,所以系统环境变量的本质就是系统给它开辟空间,给它变量的名字和内容。
  1. 查看系统中的环境变量的方法。

    • env命令可以显示系统中的所有环境变量:

      image-20241110184907698

    • echo $变量名可以打印出某一个环境变量的值:

      image-20241110185025655

  2. 认识系统Linux中常见的环境变量:

    • PATH:指定命令搜索路径,当你执行一个命令系统会按照PATH环境变量列出的路径去寻找这个命令,如果找到了就会执行它,没找到就会报错。

      image-20241110203154516

    • PWD:存储当前所处目录的绝对路径,当你使用cd命令切换 目录,PWD变量会自动更新,pwd命令不依赖于PWD环境变量,而是通过系统调用函数getcwd获取当前所处路径,就算你手动修改了PWD变量的值,敲pwd命令仍能正确显示当前所处路径。

      image-20241110203732269

      image-20241110203859035

    • USER:存储当前的用户名。

      image-20241110204017105

    • HOME:存储当前用户的主目录绝对路径。很多软件会根据这个环境变量,将配置文件放入主目录中,如.vimrc.bashrc。这样做的目的有很多,比如可以做到个性化配置可以让不同的用户相互不干扰。

      image-20241110204136311

    • LANG:指定了系统使用的语言,en_US表示美国英语,zh_CN表示简体中文。还指定了字符编码,常见的字符编码包括 UTF-8ISO-8859-1 等。例如,en_US.UTF-8 表示使用 UTF-8 编码的美国英语。

      image-20241110205007848

  3. 环境变量具有全局属性,它能被系统中所有进程和子进程使用,C语言中main函数的参数env就是来接受父进程bash的环境变量的。

    #include<stdio.h>
    #include <stdlib.h>
    #include<string.h>
    
    int main(int argc,char* argv[],char* env[])
    {
     for(int i = 0;env[i] != NULL;i++)
     {
       printf("%s\n",env[i]);
     }
    
     return 0;
    }
    

    运行结果:

    image-20241111083241732

    • argvenv字符串数组最后一个值保存的NULL

      image-20241111083825486

  4. 修改系统中的环境变量:

    • 在当前终端会话中临时设置一个环境变量,使用命令export 变量名=值

      image-20241111084558488

    • 使用unset 变量名删除我们当前终端的环境变量,也是临时删除。

      image-20241111084820251

    • 永久设置/删除,编辑配置文件~/.bashrc

    https://gitee.com/xbtwwj/typora-image-bed/raw/master/Image/202411110859964.png

    • 环境变量的来源多样,~/.bashrc 文件只是其中之一,它是一个用户级的配置文件,用户级的配置文件还有其它,除了用户级配置文件,系统级的配置文件/etc目录中也有配置文件可以配置环境变量。
  • 本人知识、能力有限,若有错漏,烦请指正,非常非常感谢!!!
  • 转发或者引用需标明来源。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/913291.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024 第五次周赛

A: 直接遍历即可 #include<bits/stdc.h> using namespace std;typedef long long ll; typedef pair<ll, ll>PII; const int N 2e6 10; const int MOD 998244353; const int INF 0X3F3F3F3F;int n, m; int main() {cin >> n;int cnt 0;for(int i 0; i …

gitlab无法创建合并请求是所有分支都不显示

点击Merge Requests ------> New merge request 创建新的合并请求时&#xff0c;在Source branch和Target branch中一个分支都不显示 排查思路&#xff1a; 1.怀疑是权限问题。 发现只有我的一个账号出现&#xff0c;检查了账号的权限&#xff0c;尝试了master、develop角色…

Linux中给普通账户一次性提权

我在以前文章中Linux常见指令大全&#xff08;必要知识点&#xff09;-CSDN博客 写过sudo的概念与用法。其实本质就是提权用的但是在某些场景下就算提权了也不能使用。 例如&#xff1a;打开主工作目录 他不相信你这个用户&#xff0c;虽然你是erman 解决方法 使用root账号打开…

【C++】—掌握STL string类:string的模拟实现

文章目录 &#x1f49e;1.浅拷贝&#x1f49e;2.深拷贝&#x1f49e;3. string类的模拟实现&#x1f49e;3.1 string的构造函数&#x1f49e;3.2 string的析构函数&#x1f49e;3.3 string的拷贝构造&#x1f49e;3.4 string的size&#x1f49e;3.5 string的operator[]&#x1…

详解基于C#开发Windows API的SendMessage方法的鼠标键盘消息发送

在C#中&#xff0c;SendMessage方法是一个强大的工具&#xff0c;它允许我们与Windows API交互&#xff0c;模拟键盘和鼠标事件。本文将详细介绍如何使用SendMessage方法来发送鼠标和键盘消息。 1. SendMessage方法概述 SendMessage是Windows API中的一个函数&#xff0c;它用…

15.UE5等级、经验、血条,魔法恢复和消耗制作

2-17 等级、经验、血条、魔法消耗_哔哩哔哩_bilibili 目录 1.制作UI&#xff0c;等级&#xff0c;经验&#xff0c;血条 ​2.为属性面板绑定角色真实的属性&#xff0c;实现动态更新 3.魔法的消耗和恢复 1.制作UI&#xff0c;等级&#xff0c;经验&#xff0c;血条 创建控…

<项目代码>YOLOv8 玉米地杂草识别<目标检测>

YOLOv8是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一个回归问题&#xff0c;能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法&#xff08;如Faster R-CNN&#xff09;&#xff0c;YOLOv8具有更高的…

现场工程师日记-MSYS2迅速部署PostgreSQL主从备份数据库

文章目录 一、概要二、整体架构流程1. 安装 MSYS2 环境2. 安装postgresql 三、技术名词解释1.MSYS22.postgresql 四、技术细节1. 创建主数据库2.添加从数据库复制权限3. 按需修改参数&#xff08;1&#xff09;WAL保留空间&#xff08;2&#xff09;监听地址 4. 启动主服务器5.…

堆排序与链式二叉树:数据结构与排序算法的双重探索

大家好&#xff0c;我是小卡皮巴拉 文章目录 目录 引言 一.堆排序 1.1 版本一 核心概念 堆排序过程 1.2 版本二 堆排序函数 HeapSort 向下调整算法 AdjustDown 向上调整算法 AdjustUp 二.链式二叉树 2.1 前中后序遍历 链式二叉树的结构 创建链式二叉树 前序遍历…

【LinuxC编程】06 - 守护进程,线程

进程组和会话 概念和特性 进程组&#xff0c;也称之为作业。BSD于1980年前后向Unix中增加的一个新特性。代表一个或多个进程的集合。每个进程都属于一个进程组。在waitpid函数和kill函数的参数中都曾使用到。操作系统设计的进程组的概念&#xff0c;是为了简化对多个进程的管…

【MongoDB】MongoDB的聚合(Aggregate、Map Reduce)与管道(Pipline) 及索引详解(附详细案例)

文章目录 MongoDB的聚合操作&#xff08;Aggregate&#xff09;MongoDB的管道&#xff08;Pipline操作&#xff09;MongoDB的聚合&#xff08;Map Reduce&#xff09;MongoDB的索引 更多相关内容可查看 MongoDB的聚合操作&#xff08;Aggregate&#xff09; 简单理解&#xff…

Python的函数(补充浅拷贝和深拷贝)

一、定义 函数的定义&#xff1a;实现【特定功能】的代码块。 形参&#xff1a;函数定义时的参数&#xff0c;没有实际意义 实参&#xff1a;函数调用/使用时的参数&#xff0c;有实际意义 函数的作用&#xff1a; 简化代码提高代码重用性便于维护和修改提高代码的可扩展性…

Unity常见问题合集(一)

PS&#xff1a;不定期更新...... 目录 &#xff08;1&#xff09;无法关闭自动编译&#xff08;Edit — Preference — General — Auto Refresh&#xff09; &#xff08;1&#xff09;无法关闭自动编译&#xff08;Edit — Preference — General — Auto Refresh&#xff0…

HTB:Sightless[WriteUP]

目录 连接至HTB服务器并启动靶机 使用nmap对靶机TCP端口进行开放扫描 继续使用nmap对靶机开放的TCP端口进行脚本、服务扫描 首先尝试对靶机FTP服务进行匿名登录 使用curl访问靶机80端口 使用浏览器可以直接访问该域名 使用浏览器直接访问该子域 Getshell 横向移动 查…

深度学习-神经网络基础-网络搭建-损失函数-网络优化-正则化方法

一. 神经网络搭建和参数计算 一个继承(nn.model), 两个方法(init, forward) 简介 在pytorch中定义深度神经网络其实就是层堆叠的过程&#xff0c;继承自nn.Module&#xff0c;实现两个方法&#xff1a; init方法中定义网络中的层结构&#xff0c;主要是全连接层&#xff0c;…

全彩LED显示屏有几种安装方式?

全彩LED显示屏的安装方式多样&#xff0c;根据不同的使用场景和安装环境&#xff0c;可以选择最合适的安装方法。以下是一些常见的全彩LED显示屏安装方式&#xff1a; 室内显示屏安装方式 吊装&#xff1a;适用于室内承重混凝土顶&#xff0c;可以使用标准吊件&#xff0c;吊杆…

ZISUOJ 2024算法基础公选课练习二

一、前言 先把代码丢上来&#xff0c;后续再补上思路 二、题目总览 三、具体题目 3.1 问题 A: 成绩排序1 参考代码 简单排序 #include <bits/stdc.h> using i64 long long;int main() {std::cin.tie(nullptr)->sync_with_stdio(false);int t 1;std::cin >&g…

阿里云智能语音交互产品试用,基于语音识别、语音合成、自然语言理解

VER&#xff1a;2024年1月25日 17:29:33 智能语音交互产品基于语音识别、语音合成、自然语言理解 新开通智能语音交互服务用户&#xff0c;可享有3个月免费试用期&#xff0c;试用期间将不会产生费用 智能语音交互产品基于语音识别、语音合成、自然语言理解等技术&#xff0c…

服务器被攻击排查记录

起因 我的深度学习的所有进程突然被killed&#xff0c;我以为是检修&#xff0c;后面发现好像简单的python代码可以正常运行。但是我的训练进程一启动就会被killed 第一时间没有用htop查看cpu&#xff0c;用top看着挺正常的&#xff0c;但是后面看htop&#xff0c;全是绿的&a…

安卓好软-----电脑端查看apk全部信息的工具 查看包名 名称以及权限等等

有时候从网络下载的应用很多是英文。时间久了会忘记到底是什么apk应用。这款工具可以方便的查看apk应用的名称 包名以及各种权限 图标 大小版本号等等。方便用户随时查看 APK Helper能够详细地获得安装包名、软件名称、APK证书、真实版本号、要求的手机版本、系统权限、以及证书…