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

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         //father
 27         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         //child
 10         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.mfbz.cn/a/557974.html

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

相关文章

牛客Linux高并发服务器开发学习第三天

静态库的使用(libxxx.a) 将lession04的文件复制到lession05中 lib里面一般放库文件 src里面放源文件。 将.c文件转换成可执行程序 gcc main.c -o app main.c当前目录下没有head.h gcc main.c -o app -I ./include 利用-I 和head所在的文件夹&#xff0c;找到head。 main.c…

进程控制相关

进程终止 进程终止时&#xff0c;操作系统要释放对应进程申请的相关内核数据结构和对应的代码和数据。其不本质就是释放进程申请的系统资源。 进程终止的常见方式&#xff1a; 1、代码运行完毕且结果正确。 2、代码运行完毕但结果不正确。 3、代码没运行完&#xff0c;进程…

【Entity Framework】闲话EF中批量配置

【Entity Framework】闲话EF中批量配置 文章目录 【Entity Framework】闲话EF中批量配置一、概述二、OnModelCreating中的批量配置元数据API的缺点 三、预先约定配置忽略类型默认类型映射预先约定配置的限制约定添加新约定替换现有约定约定实现注意事项 四、何时使用每种方法进…

通过实例学C#之ArrayList

介绍 ArrayList对象可以容纳若干个具有相同类型的对象&#xff0c;那有人说&#xff0c;这和数组有什么区别呢。其区别大概可以分为以下几点&#xff1a; 1.数组效率较高&#xff0c;但其容量固定&#xff0c;而且没办法动态改变。 2.ArrayList容量可以动态增长&#xff0c;但…

使用go和消息队列优化投票功能

文章目录 1、优化方案与主要实现代码1.1、原系统的技术架构1.2、新系统的技术架构1.3、查看和投票接口实现1.4、数据入库MySQL协程实现1.5、路由配置1.6、启动程序入口实现 2、压测结果2.1、设置Jmeter线程组2.2、Jmeter聚合报告结果&#xff0c;支持11240/秒吞吐量2.3、Jmeter…

vue 一键更换主题颜色

这里提供简单的实现步骤&#xff0c;具体看自己怎么加到项目中 我展示的是vue2 vue3同理 在 App.vue 添加 入口处直接修改 #app { // 定义的全局修改颜色变量--themeColor:#008cff; } // 组件某些背景颜色需要跟着一起改变&#xff0c;其他也是同理 /deep/ .ant-btn-primar…

『FPGA通信接口』汇总目录

Welcome 大家好&#xff0c;欢迎来到瑾芳玉洁的博客&#xff01; &#x1f611;励志开源分享诗和代码&#xff0c;三餐却无汤&#xff0c;顿顿都被噎。 &#x1f62d;有幸结识那个值得被认真、被珍惜、被捧在手掌心的女孩&#xff0c;不出意外被敷衍、被唾弃、被埋在了垃圾堆。…

【Linux学习】Linux编辑器-vim使用

这里写目录标题 1. &#x1f320;vim的基本概念&#x1f320;2. vim的基本操作&#x1f320;3.vim异常处理&#x1f320;4. vim正常模式的相关命令&#x1f320;5. vim末&#xff08;底&#xff09;行模式相关命令 vi/vim都是多模式编辑器&#xff0c;不同的是vim是vi的升级版本…

开发与产品的战争之自动播放视频

开发与产品的战争之自动播放视频 起因 产品提了个需求&#xff0c;对于网站上的宣传视频&#xff0c;进入页面就自动播放。但是基于我对chromium内核的一些浅薄了解&#xff0c;我当时就给拒绝了: “浏览器不允许”。&#xff08;后续我们浏览器默认都是chromium内核的&#…

2024年华中杯数模竞赛A题完整解析(附代码)

2024年华中杯数模竞赛A题 基于动态优化的太阳能路灯光伏板朝向以最大化能量收集研究摘要问题重述问题分析模型假设符号说明 代码问题一 完整资料获取 基于动态优化的太阳能路灯光伏板朝向以最大化能量收集研究 摘要 随着可再生能源技术的发展&#xff0c;太阳能作为一种清洁的…

C++类与对象(中)②

目录 1.赋值运算符重载 1.1运算符重载 1.2赋值运算符重载 1.2.1赋值运算符重载格式 1.2.2赋值运算符只能重载成成员函数不能重载成全局函数 1.2.3同拷贝函数一样&#xff0c;如果类是形如日期类这样变量全是内置类型的&#xff0c;赋值运算符就必须自己实现&#xff0c;…

Spectre-v1 简介以及对应解决措施

文章目录 前言一、Variant 1: Exploiting Conditional Branches.二、 BACKGROUND2.1 Out-of-order Execution2.2 Speculative Execution2.3 Branch Prediction2.4 The Memory Hierarchy2.5 Microarchitectural Side-Channel Attacks2.6 Return-Oriented Programming 三、 ATTAC…

大学生简历大赛演讲稿(6篇)

大学生简历大赛演讲稿&#xff08;6篇&#xff09; 以下是六篇大学生简历大赛演讲稿的范文&#xff0c;供您参考&#xff1a; 范文一&#xff1a;展现真我&#xff0c;点亮未来 尊敬的评委、亲爱的同学们&#xff1a; 大家好&#xff01; 今天&#xff0c;我站在这里&#xf…

区块链实验室(35) - 编译solana for ARM64版

今天终于成功编译solana for arm64版&#xff0c;编译时间巨长。见下图所示。编译步骤详见solana网站https://github.com/solana-labs/solana和https://docs.solanalabs.com/。

【C语言】【数据结构】项目实践——贪吃蛇游戏(超详细)

前言 本篇博客我们来实现一个小游戏项目——贪吃蛇&#xff0c;相信肯定很多人都玩过&#xff0c;那么整个贪吃蛇是怎么实现出来的那&#xff0c;这个项目用到了很多方面的知识&#xff1a;C语言函数、枚举、结构体、动态内存管理、预处理指令、链表、Win32 API等。我们就通过这…

nodejs工具模块学习

util 是一个Node.js 核心模块&#xff0c;提供常用函数的集合&#xff1b; util.inspect(object,[showHidden],[depth],[colors]) 是一个将任意对象转换 为字符串的方法&#xff0c;通常用于调试和错误输出&#xff1b; 如果只有一个参数 object&#xff0c;是要转换的对象&…

网工内推 | 兴业银行总行正编,科技运维部,硕士以上学历

01 兴业银行 招聘岗位&#xff1a;安全渗透专家 职责描述&#xff1a; 1.负责牵头组织本行红蓝对抗、攻防演练等工作&#xff1b; 2.负责牵头制定有效的渗透测试方案&#xff0c;开展对本行防御体系的验证工作&#xff1b; 3.负责牵头组织本行各类应用系统的渗透测试与漏洞扫…

java的Spring XML和注解解析深入理解

正文 熟悉IOC体系结构 要学习Spring源码&#xff0c;我们首先得要找准入口&#xff0c;那这个入口怎么找呢&#xff1f;我们不妨先思考一下&#xff0c;在Spring项目启动时&#xff0c;Spring做了哪些事情。这里我以最原始的xml配置方式来分析&#xff0c;那么在项目启动时&a…

大型网站系统架构演化实例_5.使用反向代理和CDN加速网站响应

1.使用反向代理和CDN加速网站响应 随着网站业务不断发展&#xff0c;用户规模越来越大&#xff0c;由于区域的差别使得网络环境异常复杂&#xff0c;不同地区的用户访问网站时&#xff0c;速度差别也极大。有研究表明&#xff0c;网站访问延迟和用户流失率正相关&#xff0c;网…

二叉检索树(定义、意义、存储数据元素形式),二叉检索树插入方法的图解和实现

1、二叉检索树&#xff1a; &#xff08;1&#xff09;定义 二叉检索树的任意一个结点&#xff0c;设其值为k&#xff0c;则该节点左子树中任意一个结点的值都小于k&#xff1b;该节点右子树中任意一个节点的值都大于或等于k 这里的比较规则可以是针对数字的&#xff0c;也可…
最新文章