Linux进程——Linux进程间切换与命令行参数

前言:在上一篇了解完进程状态后,我们简单了解了进程优先级,然后遗留了一点内容,本篇我们就来研究进程间的切换,来理解上篇提到的并发。如果对进程优先级还有没理解的地方可以先阅读:

Linux进程优先级


在这里插入图片描述


本篇主要内容:

  • 进程间的切换
  • Linux进程调度队列
  • 命令行参数
  • 了解环境变量

在这里插入图片描述


目录

  • 1. 进程间的切换
  • 2. Linux进程调度队列
    • 2.1 活跃队列
    • 2.2 过期队列
  • 3. 命令行参数
  • 4. 环境变量
  • 5. 总结


1. 进程间的切换

在之前我们提到过CPU在调度进程时,每一个进程不是占有CPU就一直运行,每隔一段时间,自动被从CPU上剥离下来,因此必定会有进程与进程之间的切换!

但是进程没有运行结束就被剥离下来,那它的数据怎么办?

在这里插入图片描述
事实上:进程在切换时会不断对自己的数据进行保存和恢复,保存是保存寄存器中的数据,而不是寄存器本身,并且这些数据会被保存到进程的PCB里面

进程在进行高并发运行时,是通过多个进程间来回快速的切换,在一个时间段内,让多个代码同时推进这就是并发

而在CPU中当另一个进程切换过来时,CPU不会删除之前的数据,之前的数据会被新切换过来的数据覆盖!


2. Linux进程调度队列

下图是Linux2.6内核中进程队列的数据结构,之间关系也已经给大家画出来,方便大家理解,而我们主要讲的就是两个小框,也就是活跃进程过期进程

在这里插入图片描述


2.1 活跃队列

在LInux进程优先级那里我们提到过优先级的范围是[60 , 99]这40个等级,而在调度队列的140个等级中,前100个我们不用管,后面40个等级正好对应我们普通优先级的等级

在这里插入图片描述
CPU运行时,会从优先级高的往下扫描,依次扫描完队列,如果存在进程则运行。


当我们在运行到优先级为99的时候,这时出现了一个优先级为80的进程,该怎么办难道我们要重新返回吗?

  • 当然是不可能返回的,所以我们需要第二个队列 – 过期队列

2.2 过期队列

如果一个活跃进程的一个进程正在运行,但又出现了一个优先级高的进程,该进程是不会放入活跃队列中的,而是放入过期队列来等待调度。

  • 如果一直放入活跃队列的话,优先级低的可能永远不会调度,会造成进程饥饿
  • 所以一般出现优先级高的新进程时,只允许往过期队列插入

因此,在不断调度的过程中,活跃进程里面的进程不断在减少,过期队列的进程一直在增加,那么如果活跃进程里的进程调度完之后,该怎么继续调度呢?

void *active // 活跃队列
void *expired // 过期队列

事实上,我们活跃队列和过期队列是由这两个指针控制
在这里插入图片描述

当我们在调度完一个队列时,将活跃进程和过期进程的内容交换,CPU依然处理活跃队列的进程

在这里插入图片描述


3. 命令行参数

在我们之前的学习时,我们写的main函数都是不带参数的,但是其实它也是可以带参数的,那么让我们来了解以下!

    1 int main(int argc, char *argv[])2 {                                                                                                                                                                                    3     return 1;4 }  

而这两个参数就是我们要学习的命令行参数。这两个参数:
argv表示指针数组,
argc表示数组元素的个数

让我们通过一个例子来更好的了解命令行参数

  1  #include<stdio.h>2 #include<stdlib.h>3 4 int main(int argc, char *argv[])5 {6     int i = 0;7     for(i = 0; i < argc; i++)                                                                                                                                                          8     {9         printf("%d: %s\n",i, argv[i]);10     }11     return 1;12 }

在这里插入图片描述
在这里插入图片描述

当我们运行可执行程序时,它将所有的内容当成一个大的字符串,以空格为分隔符,分割多个字串

将命令行输入的字符串放入argv数组是操作系统干的


既然main函数有这个功能,我们不妨来写一段有趣的代码

  1 #include<stdio.h>2 #include<stdlib.h>3 #include<string.h>4 int main(int argc, char *argv[])5 {6     if(argc != 4)7     {8         printf("Use error\nUsage: %s op[-add|sub|mul|div] d1 d2\n", argv[0]);9         return 1;10     }11     // 程序一定会有4个命令行参数,第一个参数是程序名12     int x = atoi(argv[2]);13     int y = atoi(argv[3]);14     if(strcmp(argv[1],"-add") == 0)15     {16         printf("%d + %d = %d\n", x, y, x+y);17     }18     else if(strcmp(argv[1],"-sub") == 0)19     {    20         printf("%d - %d = %d\n", x, y, x-y);21     }22     else if(strcmp(argv[1],"-mul") == 0)23     {24         printf("%d * %d = %d\n", x, y, x*y);25     }26     else if(strcmp(argv[1],"-div") == 0)27     {28         if(y == 0)     29         {                               30             printf("div zero error\n");31         }32         else{                                                      33             printf("%d / %d = %d\n", x, y, x/y);                                                                                                                                       34         }                                                 35     }                                 36     else{                                             37         printf("Use error\n");38     }      39     return 1;40 }                 

让我们来看一下:

命令行参数实现计算机程序

当然,命令行参数使用必须带选项


我们也可以是用命令行参数来实现一个自己的touch指令

  1 #include<stdio.h>2 #include<stdlib.h>34 int main(int argc, char *argv[])  5 {  6     if(argc != 2)  7     {  8         printf("touch: missing file operand\n");9         return 1;10     }                                                                                                                                                                                  11     FILE *fp = fopen(argv[1], "w");                                                                                             12     fclose(fp); 13     return 1;14 }

我们来执行一下命令行参数下的touch指令

命令行参数实现touch

命令行参数,可以支持各种指令级别的命令行选项的设置


4. 环境变量

在学习环境变量之前,先解决几个问题。

  • 为什么在执行系统的指令时可以直接使用
  • 而我们自己写的程序需要加./

而这些其实都和环境变量有关系

抛开环境变量,直接来看,.代表当前目录,实则是让操作系统能够找到我们程序的位置。而系统指令正是由于环境变量的存在能让操作系统能够直接找到并执行。

而与这有联系的环境变量是PATH保存程序的默认搜索路径的环境变量

我们可以用指令查看环境变量PATH
指令:echo $PATH

在这里插入图片描述
每个冒号表示一段路径,执行程序时会默认搜索这些路径,而我们的程序不在这些路径所以要加上./,那如果我们将程序所在路径添加到环境变量下,能不能脱离./?

显而易见,当然是可以的!!!


那我们如何将自己的路径添加到环境变量中呢?

  • 其实环境变量是可以通过指令来修改的!

指令: PATH=$PATH:路径


先用pwd指令找到当前路径
在这里插入图片描述


再使用指令将当前位置添加到环境变量中
在这里插入图片描述


最后我们不带./执行一下可执行程序
**在这里插入图片描述
发现我们在执行刚刚编写的可执行程序时,已经不需要带上./


注意:在每次重启Xshell时,都会恢复默认路径!!!


5. 总结

本篇我们主要了解了以下知识:进程间的切换,Linux进程调度队列,命令行参数,环境变量,当然环境变量我们还只接触到了它的冰山一角,还有很多知识等待着我们发掘!让我们下篇了解剩下的几个环境变量!

谢谢大家支持本篇到这里就结束了

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python程序设计 函数(三)

练习十一 函数 第1关&#xff1a; 一元二次方程的根 定义一个函数qg&#xff0c;输入一元二次方程的系数a,b,c 当判别式大于0&#xff0c;返回1和两个根 当判别式等于0&#xff0c;返回0和两个根 当判别式小于0&#xff0c;访问-1和两个根 在主程序中&#xff0c;根据函数返回…

Vue3:menu导航栏出现多个同一跳转路径的菜单处理

文章目录 需求整理实现思路实现过程 需求整理&#xff0c;实现思路 最近公司想将之前老的项目整理出来&#xff0c;因为这个老项目内容太杂什么页面都往里面塞&#xff0c;导致菜单特别多&#xff0c;公司就像将这个老的项目迁出来&#xff0c;这个旧的项目本来是后端PHP写的。…

【3dmax笔记】035: 车削修改器

一、车削修改器介绍 车削&#xff1a;图形通过绕轴旋转来创建三维效果。 开放的样条线&#xff0c;车削之后是面片。闭合的样条线&#xff0c;车削之后&#xff0c;是实体。 一、车削修改器实例 绘制高脚杯&#xff0c;首先在前视图绘制如下二维图形。 添加一个车削的修改器…

LeetCode509:斐波那契数(使用动态规划)

题目描述 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n) F(n - 1) F(n - 2)&#xff0c;其中 n > 1…

【Linux】gcc/g++的使用

&#x1f389;博主首页&#xff1a; 有趣的中国人 &#x1f389;专栏首页&#xff1a; Linux &#x1f389;其它专栏&#xff1a; C初阶 | C进阶 | 初阶数据结构 小伙伴们大家好&#xff0c;本片文章将会讲解Linux中gcc/g使用的相关内容。 如果看到最后您觉得这篇文章写得不错…

深入了解 NumPy:深度学习中的数学运算利器

文章目录 1. 导入NumPy2. 创建NumPy数组3. 数组的算术运算4. N维数组4.1 创建和操作多维数组4.2 高维数组 5. NumPy的广播功能5.1 基本广播示例5.2 更复杂的广播示例 6. 访问数组元素6.1 基于索引的访问6.2 遍历数组6.3 基于条件的访问6.4 高级索引6.5 性能考虑 在深度学习和数…

VisualGDB : 在windows上开发和调试Linux代码(一)

传送门&#xff1a; 《VisualGDB &#xff1a; 解决编码导致的编译错误》 一、补充windows上 VisualGDB的安装 这里给大家附一个官方的下载路径&#xff1a;https://visualgdb.com/download/&#xff0c;根据自己的系统选择下载 笔者另附一个云盘的下载路径 VisualGDB https…

BACnet转MQTT网关智联楼宇json格式自定义

智能建筑的BACnet协议作为楼宇自动化领域的通用语言&#xff0c;正逐步迈向更广阔的物联网世界。随着云计算和大数据技术的飞速发展&#xff0c;如何将BACnet设备无缝融入云端生态系统&#xff0c;成为众多楼宇管理者关注的焦点。本文将以一个实际案例&#xff0c;揭示BACnet网…

spring高级篇(八)

本篇对Spring MVC 的执行流程做一个简单总结 MVC执行流程总结 当浏览器发送一个请求&#xff0c;例如http://localhost:8080/hello&#xff0c;请求到达服务器后&#xff0c;一般会进行如下操作&#xff1a; 1、首先会经过DispatcherServlet&#xff0c;默认映射路径为 /&…

element-plus el-cascader 懒加载实现-省市区街道选择及回显

大概思路&#xff1a; 准备一个接口可以通过父Id,查询到下一级省市区街道的信息&#xff1b;如下方的getRegionListOne确定后端的数据结构&#xff0c;需要在created里边处理数据回显逻辑el-cascader接收的数据格式是[‘’,‘’,‘’];后端的数据格式多为[{provinceId: ‘’, …

贪心算法(活动选择、分数背包问题)

一、贪心算法 贪心算法是指&#xff1a;在对问题求解时&#xff0c;总是做出在当前看来是最好的选择&#xff0c;而不从整体最优考虑&#xff0c;做出的仅是在某种意义上的局部最优解。 …

从零开始的软件测试学习之旅(九)jmeter直连数据库及jmeter断言,关联

jmeter直连数据库及断言,关联 jmeter直连数据库步骤jmeter断言jmeter逻辑控制器if控制器ForEach控制器循环控制器 Jmeter关联Jmeter关联XPath提取器Jmeter关联正则表达式提取器二者比较跨线程组关联 每日复习 jmeter直连数据库 概念 这不叫直连:Jmeter -> java/python 提供的…

【linuxC语言】fcntl和ioctl函数

文章目录 前言一、功能介绍二、具体使用2.1 fcntl函数2.2 ioctl函数 三、拓展&#xff1a;填写arg总结 前言 在Linux系统编程中&#xff0c;经常会涉及到对文件描述符、套接字以及设备的控制操作。fcntl和ioctl函数就是用来进行这些控制操作的两个重要的系统调用。它们提供了对…

JavaEE 多线程详细讲解(1)

1.线程是什么 &#xff08;shift F6&#xff09;改类名 1.1.并发编程是什么 &#xff08;1&#xff09;当前的CPU&#xff0c;都是多核心CPU &#xff08;2&#xff09;需要一些特定的编程技巧&#xff0c;把要完成的仍无&#xff0c;拆解成多个部分&#xff0c;并且分别让…

Leetcode—933. 最近的请求次数【简单】

2024每日刷题&#xff08;128&#xff09; Leetcode—933. 最近的请求次数 实现代码 class RecentCounter { public:RecentCounter() {}int ping(int t) {q.push(t);while(t - 3000 > q.front()) {q.pop();}return q.size();} private:queue<int> q; };/*** Your Re…

嵌入式学习69-C++(Opencv)

知识零碎&#xff1a; QT的两种编译模式 1.debug 调试模式 …

c 双向链表

图片 #include <stdio.h> #include <stdlib.h> #include <string.h>int main(void){ struct film{char name[20];int id;struct film *pre; //前向指针struct film *next; //后向指针 };struct film *headNULL;struct film *ls,*lspre,*work;in…

rabbitmq集群搭建失败解决

1. 现象 1. 三台机器都已经修改hosts&#xff0c;各个节点ping节点名正常 2. erlang.cookie各节点值一样 执行下面步骤加入失败 rabbitmqctl stop_app # 停止rabbitmq服务 rabbitmqctl reset # 清空节点状态 rabbitmqctl join_cluster rabbitrabbitmq3 rabbitmqctl start_ap…

通过AOP实现项目中业务服务降级功能

最近项目中需要增强系统的可靠性&#xff0c;比如某远程服务宕机或者网络抖动引起服务不可用&#xff0c;需要从本地或者其它地方获取业务数据&#xff0c;保证业务的连续稳定性等等。这里简单记录下业务实现&#xff0c;主要我们项目中调用远程接口失败时&#xff0c;需要从本…

全栈开发之路——前端篇(5)组件间通讯和接口等知识补充

全栈开发一条龙——前端篇 第一篇&#xff1a;框架确定、ide设置与项目创建 第二篇&#xff1a;介绍项目文件意义、组件结构与导入以及setup的引入。 第三篇&#xff1a;setup语法&#xff0c;设置响应式数据。 第四篇&#xff1a;数据绑定、计算属性和watch监视 辅助文档&…