【解锁创意之门:环境变量引领你的编程奇思妙想】(上)

简介: 【解锁创意之门:环境变量引领你的编程奇思妙想】

【本节重点】


  • 了解进程调度,Linux进程优先级,理解进程竞争性与独立性,理解并行与并发
  • Linux的调度与切换,了解Linux2.6内核中进程队列的数据结构
  • 理解环境变量,熟悉常见环境变量及相关指令, getenv/setenv函数
  • 理解C内存空间分配规律,了解进程内存映像和应用程序区别, 认识地址空间。


1.进程优先级


前提:进程要访问某种资源,进程进行通过一定的方式(排队),确认享受资源的先后顺序。


1.1.基本概念


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


提问:优先级 vs 权限


       权限绝对的是能不能的问题,而优先级决定的是你先还是我先的问题,说白了,只要到了优先级,大概率一定是你拥有享受这个资源的权限了,只不过需要通过优先级确定先后的问题。


为什么要有优先级呢?


我们可以想一想,如果我们在食堂打饭的时候,打饭的人比学生多,那么学生就不用排队,可是现在打饭的人明显少于学习,所以学生就要排队,进程也是如此,因为系统的资源过少!但是这是一个相对概念,只有在中午去食堂买饭就需要排队,而在下午三四点去买饭就不用排队!这也就解释了CPU为什么有运行队列,因为CPU只有一个,资源过少,每个进程想获取CPU就必须要排对,进程需要通过队列确认优先级去获得CPU的访问,如果我们电脑的CPU很多,那就不需要队列了,直接运行进程就行啦。


1.2.查看系统进程



我们先写一份上面的代码,然后执行一下,同时输入在右侧输入:ps -al


ps -al 是一个用于显示进程信息的命令,常用于Linux。下面是对该命令的解释:


  • ps: 这是进程状态的缩写,是一个用于报告当前进程状态的命令。
  • -a: 显示所有终端上的进程,而不仅仅是与当前用户相关的进程。
  • -l: 以长格式显示输出。长格式包括更多的列,提供更详细的信息。


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

  • UID : 代表执行者的身份
  • PID : 代表这个进程的代号
  • PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
  • PRI :代表这个进程可被执行的优先级,其值越小越早被执行
  • NI :代表这个进程的nice值


这里我就要插几句话啦!不要把优先级想象的特别复杂,它在sturck task_struct里面就是一个整型变量,而且上面我们观察到Linux下默认优先级是80,但是Linux的优先级是可以被修改的,但是Linux优先级是有区间的,其范围是[60,99],一共40个。Linux优先级本质就是整型变量数字,数字越小,优先级越高!


1.3.PRI and NI


  • PRI也还是比较好理解的,即进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序,此值越小 进程的优先级别越高
  • 那NI呢?就是我们所要说的nice值了,其表示进程可被执行的优先级的修正数值
  • PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为:PRI(new)=PRI(old)+nice
  • 这样,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行
  • 所以,调整进程优先级,在Linux下,就是调整进程nice值
  • nice其取值范围是-20至19,一共40个级别。


1.4.PRI vs NI


  1. 需要强调一点的是,进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进程的优先级变化。
  2. 可以理解nice值是进程优先级的修正修正数据


1.5.用top命令更改已存在进程的nice:


       Linux系统允许用户调整优先级,但是不能直接让你修改PRI,而是通过修改nice值,它不是优先级,而是进程优先级的修正数据!现在我们来演示一下优先级的修改。


结果展示:


根据这个公式:PRI(new)=PRI(old)+nice,我们再恢复出原来的优先级


咦!这是什么情况!!!


nice值是通过覆盖式的写入的,但是我们的PRI不应该是80 = 90 + (-10)嘛,为什么是70呢?其实这是正常的,你想想如果我们的PRI是80,那我们的nice就是-10了,而其他进程nice值是0,这样系统的数据就不一致了,所以PRI在每一次设置的时候,PRI(old)都是80。


我们再来测试一下nice其取值范围


首先我们将nice值干到100。


然后我们将nice值干到-100。


总结:nice其取值范围是-20至19,一共40个级别,Linux优先级是有区间的,其范围是[60,99],一共40个,两个相互对应。


提问:Linux为什么调整优先级是受收限制的?


       如果允许任意进程调整优先级,用户可能会将自己的进程提升到高优先级,自己的进程抢占系统资源,使其他进程无法正常运行,无法享受到CPU等其他资源,此时其他进程很难得到资源,此时就被称为进程饥饿问题。任何得分时操作系统,调度上,都要具有较为公平的进行调度,所以就要求优先级是受收限制的。


2.Linux的调度与切换


概念准备:


  1. 进程在运行的时候,放在CPU上,必须直接把代码跑完,才行吗???不行,这很明显,如果我们写一个死循环的代码,那么CPU永远都跑不完,其他进程也就永远得不到调度,那么此时系统就卡死了。所以现代操作系统都是基于时间片轮转进行轮转执行的!!!  
  2. 竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级
  3. 独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰
  4. 并行: 多个进程在多个CPU下分别,同时进行运行,这称之为 并行
  5. 并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为 并发


2.1.进程切换



我们可以在struct task_struct查看到这些硬件上下文。


所以进程切换的过程就是:进程在CPU上运行 -> 时间片用完,保存硬件上下文 -> 运行队列进程阻塞 ->时间片轮转到该进程,恢复硬件上下文。这也就是一个进程在CPU一整个周期的情况。


2.2.进程调度


前提:Linux实现进程调度算法需要考虑优先级,考虑饥饿,还要考虑效率


上图是Linux2.6内核中进程队列的数据结构,我们先不看,后面我会基于上面的画一个。


2.2.1.一个CPU拥有一个runqueue


  • 如果有多个CPU就要考虑进程个数的负载均衡问题


2.2.2.优先级


  • 普通优先级适用于一般用户进程,它们不需要对实时性有极高的要求。这些进程的调度是基于时间片轮转的,并且由操作系统决定它们在CPU上运行的时间。普通优先级:100~139(我们都是普通的优先级,想想nice值的取值范围,可与之对应!)
  • 实时优先级是为具有严格时间要求的任务设计的,这些任务需要在确定的时间内完成。实时优先级:0~99(不关心)


2.2.3.活动队列


  • 时间片还没有结束的所有进程都按照优先级放在该队列
  • nr_active: 总共有多少个运行状态的进程
  • queue[140]: 一个元素就是一个进程队列,相同优先级的进程按照FIFO规则进行排队调度,所以,数组下 标就是优先级!
  • 从该结构中,选择一个最合适的进程,过程是怎么的呢?


1. 从0下表开始遍历queue[140]

2. 找到第一个非空队列,该队列必定为优先级最高的队列

3. 拿到选中队列的第一个进程,开始运行,调度完成!

4. 遍历queue[140]时间复杂度是常数!但还是太低效了!

  • bitmap[5]:一共140个优先级,一共140个进程队列,为了提高查找非空队列的效率,就可以用5*32个 比特位表示队列是否为空,这样,便可以大大提高查找效率!


2.2.4.过期队列


  • 过期队列和活动队列结构一模一样
  • 过期队列上放置的进程,都是时间片耗尽的进程
  • 当活动队列上的进程都被处理完毕之后,对过期队列的进程进行时间片重新计算
  • 如果我们的一个进程的时间片已经轮转完,它就应该从活跃队列中剥离出来,而成为新进程进入来过期队列中。


2.2.5.active指针和expired指针


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


上图是Linux2.6内核中进程队列的数据结构,之间关系也已经给大家画出来,方便大家理解。


2.2.6.总结


       在系统当中查找一个最合适调度的进程的时间复杂度是一个常数,不随着进程增多而导致时间成本增 加,我们称之为进程调度O(1)算法!


补充:参考文档 


3.环境变量


3.1.mian参数 --- 命令行参数 --- 掌握


我们知道main函数是有形参的,只不过我们一直没有使用过,今天我们来看一下main函数的参数,看看main函数的参数是什么意思?它和密命令行参数有什么关系?


首先我们知道argv是一个指针数组,数组元素有argc个,它里面的元素类型都是char*的,而我们知道char*指向的是字符串的首地址,我们来看一下argv里面的每个char*都指向了那个字符串?


我们发现随之我们的程序执行,当我们以空格作为分隔符传入-a,-b,-c,程序按照空格为分隔符,依次传入一个一个子串到argv这个指针数组里面,同时每传入一个字串,argc的个数就会加一。现在我再来解释一下输出内容。


所以我们在命令行上输入以空格为分隔符输入的字符串,会被bash解析一个一个子串,维护成指针数组argv,同时还维护了一个计数器argc,只要是函数它就会被调用,main函数也不例外,main函数由系统调用,bash会把参数传入给main函数,所以我们的main函数就拿到了命令行上输入以空格为分隔符输入的字符串和计数器argc,然后就输出了上述的结果。整个传入main函数的参数我们可以称之为一张表,我们称之为命令行参数表,把这张表就传给当前进程,而且整张表必须以NULL为结尾。那么我们的程序还可以这样写:


【解锁创意之门:环境变量引领你的编程奇思妙想】(中):https://developer.aliyun.com/article/1425753

相关文章
|
2月前
|
存储 监控 数据可视化
科研效率神器!解锁6款协作工具的潜力
科研团队常面临任务分配、跨部门协作及数据管理的挑战。为此,推荐六款协作工具:板栗看板、Microsoft Project、Dropbox、ClickUp、Notion、Wrike。它们分别在任务可视化、资源分配、文件共享、多视图支持、模块化设计及任务依赖管理等方面表现出色,适用于不同类型和规模的科研项目。
68 1
科研效率神器!解锁6款协作工具的潜力
|
机器学习/深度学习 人工智能 Java
学会用AI:释放创意,解放双手,工作再多也不慌
随着人工智能(AI)技术日渐成熟,AI在软件开发领域的应用也更加广泛。以前我们谈到AI时,常常会想到复杂的算法和深奥的理论,但如今,AI正在悄然改变着程序员的日常工作方式。从AI代码生成模型到AI编程助手应用,它们不仅仅是一小部分,更是未来程序开发的新趋势。
|
2月前
|
人工智能 搜索推荐 算法
编程之舞:从代码到艺术的蜕变
【10月更文挑战第30天】在数字世界的无限舞台上,编程不仅仅是冰冷的逻辑和枯燥的算法。它是创造者手中的画笔,是构建梦想的乐章。本文将带你领略编程背后蕴含的艺术之美,探索如何通过代码示例将技术与创造力结合,从而让程序设计成为一种独特的艺术表达。
44 2
|
5月前
|
Swift iOS开发 UED
【绝妙创意】颠覆你的视觉体验!揭秘一款iOS应用中令人惊叹的自定义动画效果,带你领略编程艺术的魅力所在!
【8月更文挑战第13天】本文通过一个具体案例,介绍如何使用Swift与UIKit在iOS应用中创建独特的按钮动画效果。当按钮被按下时,其形状从圆形变化为椭圆形,颜色则从蓝色渐变为绿色;释放后,动画反向恢复原状。利用UIView动画方法及弹簧动画效果,实现了平滑自然的过渡。通过调整参数,开发者可以进一步优化动画体验,增强应用的互动性和视觉吸引力。
66 7
|
5月前
|
机器学习/深度学习 监控 自动驾驶
|
5月前
|
UED 存储 自然语言处理
【语言无界·体验无疆】解锁Vaadin应用全球化秘籍:从代码到文化,让你的应用畅游世界每一个角落!
【8月更文挑战第31天】《国际化与本地化实战:构建多语言支持的Vaadin应用》详细介绍了如何使用Vaadin框架实现应用的国际化和本地化,提升用户体验和市场竞争力。文章涵盖资源文件的创建与管理、消息绑定与动态加载、日期和数字格式化及文化敏感性处理等方面,通过具体示例代码和最佳实践,帮助开发者构建适应不同语言和地区设置的Vaadin应用。通过这些步骤,您的应用将更加灵活,满足全球用户需求。
70 0
|
8月前
|
存储 Shell Linux
【解锁创意之门:环境变量引领你的编程奇思妙想】(下)
【解锁创意之门:环境变量引领你的编程奇思妙想】
|
5月前
|
机器学习/深度学习 人工智能 自然语言处理
💡思维碰撞新纪元:AI如何激发职场创新灵感,让创意无限飞?
【8月更文挑战第1天】在科技飞速发展的当下,人工智能(AI)正深刻变革职场创新模式。本文对比传统与AI赋能的创新思维,展现AI如何突破界限,激发无限创意。从数据驱动的洞察到跨领域融合,再到自动化提升效率,AI让创新变得更加科学与系统。通过概念性示例,展示AI辅助下的创意生成过程,呈现AI助力下职场人士探索未来的无限可能。
93 0
|
7月前
|
机器学习/深度学习 算法 安全
解锁AIGC:软件开发的未来已来
【6月更文挑战第9天】
110 10
|
8月前
|
算法 程序员 开发者
探索编程之美:从问题到解决方案的艺术之旅
【5月更文挑战第30天】 在软件开发的世界中,每一个成功的程序都是对问题的深刻理解和创造性解决方案的结晶。本文以个人的技术感悟为线索,探讨了编程不仅仅是一门科学,更是一种艺术。我们将穿梭于代码的海洋,体验从面对复杂问题到实现优雅解决方案的过程,揭示编程之美不仅体现在技术的精妙,还体现在思维的飞跃和创新的追求。