【Linux系统】地址空间 Linux内核进程调度队列

devtools/2024/12/23 6:00:00/

1.进程的地址空间

1.1 直接写代码,看现象

  1 #include<stdio.h>2 #include<unistd.h>3 4 int g_val = 100;5 6 int main()7 {8     int cnt = 0;9     pid_t id = fork();10     if(id == 0)11     {12         while(1)13         {14             printf("I am child process,pid:%d,ppid:%d, g_val:%d,&g_val:%p\n",getpid(),getppid(), g_val, &g_val);15             sleep(1);16             cnt++;17             if(cnt == 5)18             {19                 g_val = 300;20                 printf("I am child process, change:%d->%d\n", 100, 300);21             }22         }23     }24     else 25     {26         //father27         while(1)28         {29             printf("I am child process,pid:%d,ppid:%d, g_val:%d,&g_val:%p\n",getpid(),getppid(), g_val, &g_val);30             sleep(1);31         }32     }33     return 0;34 } 

 4cf5f3f48d1b4887a559d1b6eac793ae.png

 看到上面是执行结果,我们观察到,为什么g_val的数据被子进程改变,但父进程与子进程的地址仍然相同???

300,100说明父子进程是具有独立性的!!!

没错我们已经知道进程具有独立性这个概念!

那上面执行结果怎么理解呢?

进程=内核数据结构(struct stask)+代码和数据 我们之前已经知道代码是只读的,数据有w权限吗???

父子进程共用的全局变量地址一定不是物理地址,是虚拟地址!!!

1.2 引入最基本的理解(快速)

画图讲解

 

1.3 细节问题 -- 理解

独立性:多进程运行,需要独享各种资源,多进程运行之间互不干扰。

如果父子进程不写的?未来一个全局变量,默认是被父子共享的,代码是共享(只读的)

为什么要这么干??

可不可以把数据在创建子进程的时候,全部给子进程拷贝一份?

 

1.3.1 如何理解地址空间

a.什么是划分区域

其实 我们小学时可能就有划分区域这个概念了,小学时我们在分配座位坐好后,你可能与你的同桌共用一张桌子,那么你们必然要划分工作区域咯,我们当时叫它为38线,那么此时的划分区域也就类似这样,用代码怎么表述?

其实就是一个结构体!!!

来记录你的开始位置到结束位置!

对于区域的扩张与缩小其实就是对数据的+-了!!!

 

b.理解地址空间

 地址空间就像是操作系统给进程画的大饼似的,每次都给进程说想要多少空间我都能满足,但如果真的要求得到操作系统给不了的空间大小就无法分配相应空间了!!!

1.3.2 为什么要有地址空间

 

 实际的物理内存中, 代码区, 数据区, 栈区, 堆区, 共享区, 命令行参数和环境变量。

  1. 将无序变成有序,让进程以统一的视角看待物理内存以及自己运行的各个区域。
  2. 将进程管理模块和内存管理模块进行解耦
  3. 拦截非法请求 --- 对物理内存进行保护

1.3.3 如何进一步理解页表和写时拷贝

 

 当进程访问某个变量的地址时,经地址空间、页表OS会自动识别错误,

OS识别到错误

  1. 是不是数据不在物理内存(缺页中断)
  2. 是不是数据需要写实拷贝(发生写实拷贝)
  3. 如果都不是才进行异常处理
  1 #include<stdio.h>2 #include<unistd.h>3 4 int main()5 {6     pid_t id = fork();7     if(id == 0)8     {9         //child10         while(1)11         {12             printf("I am child process, id:%d, &id: %p\n", id, &id);13             sleep(1);14         }15     }16     else if(id > 0)17     {18         //father  19         while(1)20         {21             printf("I am father process, id:%d, &id: %p\n", id, &id);                                                                                                                   22             sleep(1);23         }24     }25     return 0;26 }

 

2.Linux真正的是怎么调度的?O(1)算法

nice并不能让你任意调整,而是有范围的![-20,19)40个数字

Linux系统中每一个CPU都有一个运行队列!

这个运行队列中包含活动队列和过期队列!

 

活动队列(只出不进)

时间片还没有结束的所有进程都按照优先级放在该队列

nr_active: 总共有多少个运行状态的进程
queue[140]: 一个元素就是一个进程队列,相同优先级的进程按照FIFO规则进行排队调度,所以,数组下标就是优先级

从该结构中,选择一个最合适的进程,过程是怎么的呢?
1. 从0下表开始遍历queue[140]
2. 找到第一个非空队列,该队列必定为优先级最高的队列
3. 拿到选中队列的第一个进程,开始运行,调度完成!
4. 遍历queue[140]时间复杂度是常数!但还是太低效了!
bitmap[5]:一共140个优先级,一共140个进程队列,为了提高查找非空队列的效率,就可以用5*32个
比特位表示队列是否为空,这样,便可以大大提高查找效率!
 


过期队列(只进不出)

过期队列活动队列结构一模一样
过期队列上放置的进程,都是时间片耗尽的进程
当活动队列上的进程都被处理完毕之后,对过期队列的进程进行时间片重新计算 

active指针和expired指针
 

active指针永远指向活动队列
expired指针永远指向过期队列
可是活动队列上的进程会越来越少,过期队列上的进程会越来越多,因为进程时间片到期时一直都存在的。
没关系,在合适的时候,只要能够交换active指针和expired指针的内容,就相当于有具有了一批新的活动进程!


http://www.ppmy.cn/devtools/2852.html

相关文章

android 内存优化

一、内存需要优化的几个点 什么是内存抖动&#xff1f; 在Java中&#xff0c;每创建一个对象&#xff0c;就会申请一块内存&#xff0c;存储对象信息&#xff1b;每分配一块内存&#xff0c;程序的可用内存也就少一块&#xff1b;当 程序被占用的内存达到一定临界程度&#x…

【VTKExamples::Meshes】第 十四期 ExtractEdges

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 公众号:VTK忠粉 前言 本文分享VTK样例ExtractEdges,并解析接口vtkExtractEdges,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~…

mac安装idea、安装Tomcat,idea配置tomcat,mac安装Maven

记录一下mac安装idea、安装Tomcat&#xff0c;idea配置tomcat&#xff0c;mac安装Maven的过程&#xff0c;及遇到的问题&#xff1a; &#xff08;1&#xff09;mac安装idea&#xff1a;idea有两个版本社区版和商业版本&#xff0c;其中社区版免费但是不能安装javaEE插件&…

MySQL--数据的增删改

目录 1.添加数据 1.1、添加全部字段的数据 1.2、添加指定字段的部分数据 1.3、同时添加多条记录 1.4、插入查询结果数据 2.修改数据 2.1、更新全部数据 2.2、更新部分数据 3.删除部分数据 3.1、删除部分数据 3.2、删除全部数据 文中[ ]里 面的内容可写可不写 1.添加数…

Uniapp+基于百度智能云完成AI视觉功能(附前端思路)

本博客使用uniapp百度智能云图像大模型中的AI视觉API&#xff08;本文以物体检测为例&#xff09;完成了一个简单的图像识别页面&#xff0c;调用百度智能云API可以实现快速训练模型并且部署的效果。 uniapp百度智能云AI视觉页面实现 先上效果图实现过程百度智能云Easy DL训练图…

牛客周赛 Round 39(A,B,C,D,E,F,G)

比赛链接 官方题解&#xff08;视频&#xff09; B题是个贪心。CD用同余最短路&#xff0c;预处理的完全背包&#xff0c;多重背包都能做&#xff0c;比较典型。E是个诈骗&#xff0c;暴力就完事了。F是个线段树。G是个分类大讨论&#xff0c;出题人钦定的本年度最佳最粪 题目…

react使用npm i @reduxjs/toolkit react-redux

npm i reduxjs/toolkit react-redux 创建一个 store文件夹&#xff0c;里面创建index.js文件和子模块文件夹 index,js文件写入以下代码 import {configureStore} from reduxjs/toolkit // 导入子模块 import counterReducer from ./modules/one import two from ./modules/tw…

【go-zero】go-zero 整合MQTT协议 | 实现对MQTT的操作

一、go-zero标准项目配置 完成下面三个步骤就可以直接在svcCtx中使用MQTT 我们使用官方的MQTT库:https://github.com/eclipse/paho.mqtt.golang 1、 设置 YAML 1.1、配置如下: 除了Broker、Port、User、Pass、Ca 其余都为可选项 Mqtt:Broker: mqtt3.xxx.com# Port: 28883…