当前位置: 首页 > news >正文

Linux 进程优先级、程序地址空间、进程控制

个人主页:仍有未知等待探索-CSDN博客

专题分栏: Linux

目录

一、进程优先级

1、什么是进程优先级?

2、为什么要有优先级?

3、Linux的优先级特点、查看方式

4、命令行参数和环境变量

1.命令行参数

2.环境变量

获取环境变量的方式:

二、程序地址空间

1、进程的地址空间

2、基本理解

对于现象的解释(操作系统 -> 写时拷贝):

3、细节问题

为什么不在子进程创建的时候就直接全部拷贝一份?

4、如何理解地址空间

1.区域的划分

2.地址空间的理解

3.为什么要有地址空间

4.页表和写时拷贝的理解

5.虚拟地址的理解

6.Linux中调度

大O(1)调度算法

三、进程控制

1、进程创建

进程调度fork之后,内核的工作(步骤)

进程具有独立性的理解

fork函数的返回值

fork函数为什么会有两次返回值

fork函数常规用法

fork函数调用失败的原因

写时拷贝

2、进程终止

进程终止的意义

进程终止的三种情况

进程为什么会异常?

进程退出的原因?

进程退出判断顺序?

如何终止?

3、进程等待

进程等待是什么?

进程等待的原因

wait/waitpid

status参数是什么?

退出信息

如何理解阻塞等待子进程?

如何从status中获取到退出码和退出信息?

非阻塞等待

4、进程的程序替换

exec系列函数

解释原理

进程替换有没有创建新的进程?

怎么加载?

exec*系列的返回值

程序替换的意义

系统调用:execve


一、进程优先级

1、什么是进程优先级?

进程获取某种资源(cpu)的先后顺序。

  • task_struct 进程控制块 -> int prio;
  • Linux中优先级数字越小,优先级越高
  • 优先级和权限的区别:优先级是能执行,表示执行的顺序;而权限是能不能执行的问题。

2、为什么要有优先级?

进程访问cpu的资源始终是有限的

操作系统关于调度和有限级的原则:分时操作系统:根据时间片来进行调度 --- 保证基本的公平。

如果进程长时间不被调度,就造成了饥饿问题。

3、Linux的优先级特点、查看方式

  • Linux查看优先级的指令:ps -al
  • PRI:进程的优先级,NI:进程优先级的修正数据(用于对优先级的动态修改)。最终进程的优先级 = PRI + NI。
  • 调整优先级的指令:top --->  r ---> PID to renice -> Value(本人修改的NI值)NI值也就是nice值,不是随便调整的,而是有范围的[-20, 19]
  • 每次优先级的调整,PRI的值都是从80开始的。

4、命令行参数和环境变量

1.命令行参数

int main(int argc, char *argv[]):对于这种写法的main函数里面的参数代表着什么

是命令行字符串,程序的路径+名称 和 该进程匹配的选项。

命令行参数的意义

命令行参数的本质是交给我们不同的选项,来定制不同的程序功能

  • 父进程的数据默认能被子进程看到并访问。

  • 命令行中启动的程序,都会变成进程,都是bash的子进程。

2.环境变量

Linux中存在一些全局的设置,告诉命令行解释器,应该去哪个路径下去寻找可执行程序。

  • 可以用env指令去查看所有的环境变量:

  • 可以用echo指令打印环境变量的内容:

  • 默认我们能查到的环境变量是内存级别的,当xshell重启后,环境变量默认会恢复。
  • 环境变量不是在内存中,而是在系统对应的配置文件中。内存的环境变量,是xshell启动的时候,加载到内存中的。
  • env:一个查看环境变量的指令

    export name=value:导入环境变量的指令

    unset name:取消环境变量的指令

  • 本地变量:hello=1234,不能被子进程继承。这个helloc是本地变量,当你用env查看环境变量的时候是不会找到这个变量的。

  • environ -> 一个char**类型,存放着环境变量(unistd.h、需要声明,extern char** environ)
  • 环境变量可以被子进程拿到的。-> 环境变量默认在bash内部。

  • bash进程启动的时候,默认会给子进程形成两种表:

    argv[]命令行参数表、env[]环境变量表。bash通过各种方式交给子进程。

  • 环境变量具有系统级的全局属性,因为环境变量本身会被子进程继承下去。

  • echo、export都是内建命令(不是bash子进程创建的,而是bash执行的)。

  • 本地变量旨在本bash内部有效,无法被子进程继承下去,导成环境变量,此时才能够被获取。

获取环境变量的方式:

1、函数:获取环境变量的值:char* getenv(char* name)。

2、extern char** environ。

3、通过main函数的参数。

二、程序地址空间

1、进程的地址空间

现象:在一段代码中,子进程改变了全局变量,但是在父进程中读取到的仍是原来的值,并且子进程和父进程中全局变量的地址一样。

2、基本理解

  • 每个进程都有一个独立的地址空间。
  • 每个进程都有一个独立的页表。
  • 地址空间的本质就是内核中的一个结构体对象。
  • 子进程会把父进程的大部分内核数据拷贝一份。

对于现象的解释(操作系统 -> 写时拷贝):

如果子进程要修改的值,这个值不仅仅只有子进程在使用的话,操作系统会重新开辟一块新的物理空间,将数据拷贝给新的物理空间,让子进程指向新的物理空间(修改物理内存、修改页表)。(物理内存中的代码和数据要拷贝一份、task_struct也要拷贝一份,拷贝后的内容大部分和之前是相同的)

子进程和父进程中共享变量的地址相同,其实是虚拟地址相同而已。

3、细节问题

如果父子进程不写的话,全局变量默认是被父子共享的,代码是共享的(只读)。

为什么不在子进程创建的时候就直接全部拷贝一份?

为了节省空间。并且父子进程共享的数据中,有大部分数据都是不会进行修改的 --- 按需申请。

4、如何理解地址空间

1.区域的划分

地址空间本质是内核的一个struct结构体,很多的属性都是表示范围的变量(start,end)

struct area
{int start;int end;
}

2.地址空间的理解

地址空间是一个结构体,有各种的地址划分。

如下图,

3.为什么要有地址空间

实际的物理空间,代码区、数据区、堆区、栈区、共享区、命令行参数和环境变量都是乱序的。

所以为了好管理,人为的规定了地址空间。

  • 地址空间将无序变成有序,让进程以统一的视角看待物理内存以及自己运行的各个区域。

  • 进程管理模块和内存管理模块进行解耦。

  • 拦截非法请求。

4.页表和写时拷贝的理解

5.虚拟地址的理解

程序运行后,使用的是虚拟空间的地址,而想要得到物理地址需要用页表进行映射。

最开始的时候,地址空间和页表中的数据是由操作系统在程序加载到内存中动态创建和管理的。

6.Linux中调度

在Linux中,每个cpu都会由一个运行队列。

大O(1)调度算法

三、进程控制

1、进程创建

进程调度fork之后,内核的工作(步骤)

  1. 分配新的内存块和内核数据结构给子进程。

  2. 将父进程大部分数据结构内容拷贝至子进程。

  3. 添加子进程到系统进程列表中。

  4. fork返回,开始调度器调度。

进程具有独立性的理解

子进程有自己的相关管理数据结构,虽然代码是和父进程共享的,但是数据被写时是以写时拷贝进行独立的。

fork函数的返回值

子进程返回0,父进程返回子进程的pid。

fork函数为什么会有两次返回值

在fork函数返回之前,子进程已经创建完毕,可以开始进行调度了。

fork函数常规用法

1、子进程复制父进程,是父子进程同时执行不同的代码段。

2、子进程执行一个不同的程序。

fork函数调用失败的原因

1、系统中有太多的进程。

2、实际用户的进程数超过了限制。

写时拷贝

2、进程终止

进程终止的意义

1、释放曾经的代码和数据所占用的空间。

2、释放内核数据块。 --- 可能延迟释放。(僵尸状态)

进程终止的三种情况

1、代码跑完,结果正确。

2、代码跑完,结果不正确。

2、代码执行时,出现了异常,提前退出了。

  • 结果正不正确可以通过进程的退出码决定
  • 一旦出现异常,退出码就没有任何的意义了。

pl:在用VS编程时,代码运行的时候崩溃了。 --- 本质就是os发现这个进程做了不该做的事情(如:访问了非法地址等),直接杀死了进程。

进程为什么会异常?

进程出现异常 本质上 就是因为进程收到了os发给进程的信号!

我们可以通过查看退出信号来判断进程出现异常的情况。

进程退出的原因?

可以根据退出码来进行判断,退出的原因。

进程退出判断顺序?

1、先看退出信息,判断是否是因为异常而退出的。

2、如果不是异常引起的,在看退出码,判断是否运行正常。

衡量一个进程退出,只需要退出码和退出信号

如何终止?

1、main函数中return,表示进程结束。(非main函数中return,表示函数结束)

2、调用exit函数。注意:我们代码的任意位置调用exit(int status),都表示进程退出。

3、调用_exit(int status) --- 系统调用。

3、进程等待

进程等待是什么?

任何进程在退出的情况下,一般必须要被父进程进行等待。如果父进程不管不顾,子进程变成Z状态,内存泄漏。

进程等待的原因

  • 父进程通过等待解决子进程退出的僵尸问题,回收系统资源。(一定要考虑)
  • 获取子进程退出的信息。(不一定需要)

wait/waitpid

status参数是什么?

  • 输出型参数
  • 输出子进程退出信息。

退出信息

退出信息 = 进程退出码 + 退出信号

一个int,在X86下是32位bit位,怎么存储信息如下:

如何理解阻塞等待子进程?

阻塞等待子进程的本质是父进程主动放弃CPU使用权,进入等待状态,并将其PCB从运行队列转移到等待队列中。当子进程结束时,父进程会被操作系统唤醒并重新加入到运行队列中。

如何从status中获取到退出码和退出信息?

1、退出码 = (status >> 8) & 0xFF

     退出信号 = status & 0x7F

2、WIFEXITED(status) --- 判断是不是正常退出(判断退出信号)。

      WEXITSTATUS(status) --- 获取子进程退出码。

非阻塞等待

  • waitpid的参数optionsu如果为0就是阻塞等待,如果为WNOHANG就是非阻塞等待。

  • waitpid采用非阻塞等待,本质就是检测子进程的状态变化。

pid_t > 0:  调用成功了,并且子进程退出了,父进程回收成功。

pid_t < 0:  调用失败了。

pid_t == 0:调用是成功的,只不过子进程还没退出,需要要你下一次进行重复等待。

  • 非阻塞等待的时候 + 循环 = 非阻塞轮询。

4、进程的程序替换

exec系列函数

就是用exec系列的函数,执行新的程序。

解释原理

进程替换有没有创建新的进程?

没有创建新进程。只是把新程序的代码和数据覆盖老进程。页表可能会修改一下新的映射关系,PCB属性可能会有改变。

站在被替换进程的角度,本质就是这个程序被加载到内存了!

怎么加载?

exec*系列函数类似于是一种Linux上的加载函数。

exec* 系列的函数,执行完毕之后,后续的代码不见了,被替换了。

exec*系列的返回值

exec* 函数的返回值不需要考虑,如果exec*函数运行成功了,后续代码不会被运行;如果运行失败了,才会运行后续代码。

程序替换的意义

创建子进程,让子进程完成任务:

1、让子进程执行父进程代码的一部分

2、让子进程执行一个全新的程序。

系统调用:execve

谢谢大家!!! 

相关文章:

Linux 进程优先级、程序地址空间、进程控制

个人主页&#xff1a;仍有未知等待探索-CSDN博客 专题分栏&#xff1a; Linux 目录 一、进程优先级 1、什么是进程优先级&#xff1f; 2、为什么要有优先级&#xff1f; 3、Linux的优先级特点、查看方式 4、命令行参数和环境变量 1.命令行参数 2.环境变量 获取环境变量的…...

学习笔记一

vector 在创建时指定初始大小和初始值&#xff1a; vector<int> a(5, 1) // 包含 5 个整数的 vector&#xff0c;每个值都为 1 可以使用 push_back 方法向 vector 中添加元素&#xff1a; a.push_back(7) // 将整数 7 添加到 vector 的末尾 可以使用 size(…...

Linux中信号的发送及信号的自定义捕捉方法

预备知识&#xff1a; 信号产生时进程早已知道该信号如何处理。 信号产生时进程可能并不能立即处理信号而是等到合适的时候处理。 信号其他相关常见概念 实际执行信号的处理动作称为信号递达(Delivery) 信号从产生到递达之间的状态,称为信号未决(Pending)。 进程可以选择阻…...

yum仓库的制作与使用

目录 前言&#xff1a; 1 查看系统内核 2 获取网络源 3 搭建yum网络仓库 4 rpm包的下载 4.1 将rpm包下载至本地 4.2 对下载的rpm包进行备份 5 制作本地yum源 5.1 软件仓库制作工具createrepo 5.2 使用createrepo创建本地yum仓库 6 搭建docker本地仓库 前言&#x…...

牛客周赛54:D.清楚姐姐跳格子(bfs)

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 题目描述 \,\,\,\,\,\,\,\,\,\,老妪遂递一羊皮卷轴&#xff0c;上面什么都没有&#xff0c;清楚欲问&#xff0c;老妪却缄口不言。           \,\,\,\,\,\,\,\,\,\,清楚性格刚直&…...

用户空间 lmkd

用户空间 lmkd 1、概览1.1 配置lmkd 2、lmkd2.1 lmkd启动2.2 时序图 Android LowMemoryKiller原理分析 AOSP>文档>核心主题低内>存终止守护程序 1、概览 Android Low Memory Killer Daemon &#xff1a;system/memory/lmkd/README.md Android 低内存终止守护程序 (lm…...

二叉树专题

Leetcode 104. 二叉树的最大深度 class Solution { public:int maxDepth(TreeNode* root) {if(!root) return 0;int leftd maxDepth(root -> left) 1;int rightd maxDepth(root -> right) 1;return max(leftd, rightd);} }; Leetcode 100. 相同的树 class Solution…...

Spring MVC 之简介及常见注解

一、什么是 Spring MVC Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架&#xff0c;从一开始就包含在 Spring 框架中。它的正式名称 “Spring Web MVC” 来自其源模块的名称 (Spring-webmvc)&#xff0c;但它通常被称为"Spring MVC"。 什么是Servlet呢? S…...

除了使用本地存储,还有哪些方法可以实现只出现一次的弹窗?

除了使用本地存储&#xff0c;还有以下几种方法可以实现只出现一次的弹窗&#xff1a; 1.使用 Cookie&#xff1a;可以将一个标识符存储在浏览器 Cookie 中&#xff0c;下次用户访问页面时检查 Cookie 中是否存在该标识符&#xff0c;从而判断是否需要显示弹窗。 2.使用服务器端…...

微软蓝屏事件揭示的网络安全深层问题与未来应对策略

目录 微软蓝屏事件揭示的网络安全深层问题与未来应对策略 一、事件背景 二、事件影响 2.1、跨行业连锁反应 2.2、经济损失和社会混乱 三、揭示的网络安全问题 3.2、软件更新管理与风险评估 3.2、系统复杂性与依赖关系 3.3、网络安全意识与培训 四、未来的网络安全方向…...

C#:通用方法总结—第11集

大家好&#xff0c;今天继续分享我们的通用方法系列。 下面是今天要分享的通用方法&#xff1a; &#xff08;1&#xff09;这个通用方法为Ug’校验选中体的个数&#xff1a; /// <summary> /// 输出选中体个数 /// </summary> public int CheckOneBody() { int …...

Web开发-html篇-下

这篇是接着上篇的内容&#xff0c;接着介绍html的其他标签及属性的用法&#xff0c;感兴趣的可以从我的html上篇看起 1. 超链接示例 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport&…...

【C++从小白到大牛】多态那些事儿(上)

一、多态的概念 1.1概念: 通俗来说&#xff0c;就是多种形态&#xff0c;具体点就是去完成某个行为&#xff0c;当不同的对象去完成时会产生出不同的状态。 二、 多态的定义及实现 2.1多态的构成条件 多态是在不同继承关系的类对象&#xff0c;去调用同一函数&#xff0c;产…...

网站在线查询工具箱源码分享

终极网络工具系统”(SAAS)&#xff0c;是一款功能强大的PHP脚本在线查询工具。本版集合了超过470种快速且易用的Web工具&#xff0c;为日常任务处理和开发人员提供了极大的便利。作为一款综合性的网络工具系统&#xff0c;66toolkit不仅满足了用户的基本网络需求&#xff0c;更…...

SSH简写且免密登陆终端设备

问题 通常使用ssh连接远程设备时&#xff0c;需要先执行ssh <username><ip>&#xff0c;然后再输入终端设备的用户密码。比较麻烦。 解决 可以用如下方法设置命令缩写以及免密登陆&#xff1a; 免密 首先在本地生成私钥&#xff1a; ssh-keygen -t rsa # or …...

算力共享中神经网络切片和算力分配策略

目录 神经网络切片 按照算力的分布进行网络层数切片;就是算力越强,运算神经网络层数越多 神经网络切片和算力占比进行映射 算力分配策略 get_current_shard 神经网络切片 按照算力的分布进行网络层数切片;就是算力越强,运算神经网络层数越多 神经网络切片和算力占比进…...

3章4节:R的逻辑运算和矩阵运算

逻辑运算和矩阵运算是R语言中两个重要的功能模块,前者用于逻辑判断和条件筛选,后者用于处理多维数据结构和执行线性代数运算。本文章详细介绍R语言中的逻辑运算和矩阵运算,帮助读者掌握这两类运算的基本概念、操作方法和实际应用。 一、逻辑运算 逻辑运算在编程语言中扮演着…...

使用EasyAR打包安卓操作注意

EasyAR for Scene 4.6.3 丨Unity2020.3.15f2 打包Unity注意事项 一、默认渲染管线 官方参考链接&#xff1a;ARFoundation 简单注意 1.打包设置为Android平台 2.PackageName和EasyAR中保持一致 3.Scripting Backend设置为IL2CPP&#xff0c;以及设置为ARM64 4.取消Auto …...

驾驭PyCharm:破解环境配置的迷宫

驾驭PyCharm&#xff1a;破解环境配置的迷宫 PyCharm&#xff0c;作为Python开发者的首选IDE之一&#xff0c;以其强大的功能和用户友好的界面而广受好评。然而&#xff0c;即便是最强大的工具&#xff0c;环境配置问题也可能成为开发者的拦路虎。本文将带你深入探索PyCharm中…...

大数据技术原理-Hadoop的安装

摘要 随着大数据时代的到来&#xff0c;Hadoop作为一项重要的分布式计算框架&#xff0c;其安装与配置是大数据技术学习者必须掌握的技能。本文通过实验报告的形式&#xff0c;详细记录了在虚拟机环境下安装Hadoop并配置其为伪分布式模式的全过程。实验过程中&#xff0c;遇到…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...