Linux进程学习【三】

news2025/1/24 11:31:05

✨个人主页: Yohifo
🎉所属专栏: Linux学习之旅
🎊每篇一句: 图片来源
🎃操作环境: CentOS 7.6 阿里云远程服务器

  • Perseverance is not a long race; it is many short races one after another.

    • 毅力不是一场漫长的比赛;是许多短跑一个接一个。

    四姑娘山


文章目录

  • 📘前言
  • 📘正文
    • 📖环境变量
      • 🖋️环境变量列表
      • 🖋️添加环境变量
      • 🖋️获取环境变量
    • 📖主函数参数
      • 🖋️三个参数
      • 🖋️选项调用
    • 📖进程优先级
      • 🖋️优先级查看
      • 🖋️优先级修改
    • 📖进程特点
  • 📘总结


📘前言

环境变量 是一个即陌生又熟悉的词,说陌生是因为大多数普通用户都接触不到 环境变量 配置,说熟悉是因为很多程序又都离不开 环境变量,比如编写 Java 时需要提前安装 jdk,配置好 Java 的环境,才能正常编写代码,python 也是需要配置编码环境;而在我们的 Linux 中也有环境变量,由 环境变量 构成的集合称做 环境变量表;我们还可以调整 进程 的优先级,使得 进程 运行更加灵活

环境变量


📘正文

📖环境变量

首先需要先来看看什么是 环境变量

  • 一般是指在操作系统中用来指定操作系统运行环境的一些参数
  • 例如在编译程序时,我们是不关心动态库位于什么地方,编译器链接时也只需要通过对应的 环境变量 就能找到动态库进行链接
  • 环境变量 有着自己的特殊用途,还有有些具有全局属性,可以供所有 进程 共享

环境变量 有很多个,把它们聚在一起管理,就构成了 环境变量列表

环境变量列表 中的常见 环境变量

  • PATH 系统命令搜索路径
  • USER 当前用户名
  • PWD 当前所处路径

我们可用通过指令 echo $NAME 查看当前环境变量信息(NAME 指环境变量名)

//比如查看用户信息
$ echo $USER	

查看信息

🖋️环境变量列表

下面来看看 环境变量列表 长什么样
通过指令查看

$ env

表
环境变量表是以指针数组的形式存储的
表
也可以通过 set 指令查看 环境变量表,不过 set 指令显示的内容比 env 多得多,因为 set 还会显示 本地环境变量 信息

$ set	//显示更加丰富的环境变量表

这里简单说一下 PATH 的作用

  • Linux 中的各种指令都是用 C语言 编写的程序,所以:运行指令 == 运行程序
  • PATH 环境变量中有存储各种指令(程序)的路径,当我们直接输入指令时,OS会根据 PATH 提供的路径搜索程序,找到了就会直接运行对应指令(程序)
  • 而我们自己编写的程序则是需要通过 ./可执行程序 的方式运行,因为此时路径不被包含在 PATH 变量中
  • 总之:PATH 存储路径中若包含程序,可以直接通过程序名运行程序
  • 这就是各种指令,如 lspwdtouch 的运行原理

区别
指令
我们可以通过这一特性,将自己的可执行程序路径添加到 PATH 变量中

//注意:路径为绝对路径
//不能写成 export PATH=路径	这样会把所有指令都覆盖
$ export PATH=$PATH:/home/Yohifo/linux/Explore/code/Test_2_21

添加
现在可以像指令一样直接运行程序

注意: 普通用户添加的环境变量只有本次登录有效,下次再登录时,环境变量列表会被重置

普通用户修改 环境变量列表 没什么大问题,但 root 需要谨慎了,避免造成严重后果

除此之外,我们还可以把程序写在 /usr/bin 目录下,此时也是可以直接通过程序名运行程序的

安装
如上就是安装、卸载应用原理

🖋️添加环境变量

shell 可以读取到命令和命令行,我们可以直接通过命令的方式添加 环境变量

先来看看比较简单的 本地变量 添加
环境变量表 具有全局属性,可以供所有子进程共享,倘若我们不想让 环境变量 被共享,可以设置 本地变量

$ TEST=private	//可以直接在命令行中添加本地变量

本地变量

现在的 TEST 环境变量是不被子进程共享的

如果想删除已经设置的 本地环境变量,可以通过 unset NAME 移除设置

$ unset TEST	//移除已设置的本地环境变量

想让 TEST 进入 环境变量表 也很简单,只需要加上关键字 export

$ export TEST=public	//此时环境变量已进入环境变量表

环境变量
环境变量

🖋️获取环境变量

环境变量 针对的是特定的人在特定场合干特定的事,这句话读起来有点绕,实际上:

  • 有许多 环境变量 存储的是用户的个人信息,不同用户的 环境变量表 各不相同
  • 我们可以利用 环境变量 做信息验证,根据不同变量(选项)执行不同操作

比如 ls 指令是显示当前目录下的文件信息,而 ls -a 则是显示详细信息,原理很简单,调用 ls 程序时传递了 -a 这个选项,使得程序一对比,就知道要执行显示详细信息这个操作

环境变量表具有全局属性,程序运行时,环境变量表会传递给程序使用

因此我们可以在程序中获取 环境变量

  • 通过全局变量 environ (char** 类型)获取
  • 通过函数 getenv(NAME) 获取,这个比较常用
  • 通过 main 函数中的第三个参数 char* envp[] 获取

前两种方式比较简单,可以通过一个小程序观察到,而最后一种方式 需要结合主函数参数 的知识观察,将放在下一个部分详细讲解

先来看看前两种方式获取 环境变量

#include<iostream>
#include<stdlib.h>  //getenv 需要使用这个头文件
using namespace std;

extern char** environ; //声明使用

int main()
{
  //cout << "Hello environment variable!" << endl;  //你好环境变量!
  int pos = 0;
  while(pos < 5)
  {
    cout << environ[pos] << endl; //获取部分环境变量信息
    pos++;
  }

  cout << endl << "========================" << endl << endl;

  //通过函数获取
  cout << "PWD=" << getenv("PWD") << endl;

  return 0;
}

结果

可以自己尝试通过 getenv 函数验证本地变量不进入环境变量表这个现象

指令 pwd 实现非常简单,通过 getenv("PWD") 获取信息,再输出即可,我们可以自己实现 mypwd

#include<iostream>
#include<stdlib.h>
using namespace std;

int main()
{
  //调用程序,获取环境变量信息
  cout << getenv("PWD") << endl;
  return 0;
}

模拟实现
一些不带选项,且比较简单的指令,我们是 可以直接利用函数获取 环境变量 模拟实现


📖主函数参数

main 函数有两种写法:带参与不带参,平常我们都是使用不带参数的 main 函数作为程序入口,对于函数参数很少关注,今天就来看看 main 函数中的参数吧

🖋️三个参数

main 函数中有三个参数,分别是:

  • int argc 传入程序中的元素数,./程序名 算一个
  • char* argv[] 传入程序中的元素表,由 bash 制作,传给 main 函数
  • char* envp[] 环境变量表,所谓全局性就是指 main 函数可以通过此参数获取到环境变量表的信息

配图

如何证明它们存在呢?
程序就是最好的证明

#include<iostream>
using namespace std;

int main(int argc, char* argv[], char* envp[])
{
  cout << "现在传入的有效元素数为:" << argc << endl;
  cout << "==========================" << endl;
  cout << "通过元素表打元素信息" << endl;
  int pos = 0;
  while(pos < argc)
  {
    cout << argv[pos] << endl;
    pos++;
  }
  cout << "==========================" << endl;
  cout << "使用环境变量表获取前五个环境变量信息" << endl;
  pos = 0;
  while(pos < 5)
  {
    cout << envp[pos] << endl;
    pos++;
  }
  
  return 0;
}

证明
main 函数中的三个参数各有各的作用

enpv 也可以获取环境变量,效果等价于 environ

环境变量表 能被共享的本质: 环境变量表会通过传参数的形式传给程序使用

🖋️选项调用

argv 可以实现指定指令完成指定功能的任务

首先我们需要在程序中提前设置好不同选项的运行结果

#include<iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;

//打印提示信息
void Usage(const char* str)
{
  cout << str << " -[a | b | c]" << endl;
}

int main(int argc, char* argv[], char* envp[])
{
  //首先进行身份检验
  if(strcmp(getenv("USER"), "Yohifo") != 0)
  {
    cout << "当前用户为:" << getenv("USER") << endl;
    cout << "非法使用他人程序,操作被拒绝!" << endl;
    return 0;
  }

  //确保选项只有一个
  if(argc != 2)
  {
    cout << "指令错误,尝试重新输入" << endl;
    Usage(argv[0]);
    return 0;
  }

  //验证成功后,进行选项分流
  if(strcmp(argv[1], "-a") == 0)
  {
    cout << "执行 a 任务" << endl;
    cout << "…………………………" << endl;
    cout << "任务执行完成" << endl; 
  }
  else if(strcmp(argv[1], "-b") == 0)
  {
    cout << "执行 b 任务" << endl;
    cout << "…………………………" << endl;
    cout << "任务执行完成" << endl; 
  }
  else if(strcmp(argv[1], "-c") == 0)
  {
    cout << "执行 c 任务" << endl;
    cout << "…………………………" << endl;
    cout << "任务执行完成" << endl;     
  }
  else
  {
    cout << "指令错误,尝试重新输入" << endl;
    Usage(argv[1]);
    return 0;
  }

  return 0;
}

通过不同的选项,调用不同的功能,这就是 main 函数参数存在的意义

选项会同程序名一起,构成一张表,传给 char* argv[] 参数

选项调用
这种玩法叫做 命令行参数,后续学习中将会经常用到


📖进程优先级

进程 还有优先级之分,优先级高的 进程 会被优先调用

CPU 资源是有限的,需要合理分配

  • Linux 给我们提供了修改 进程 优先级的权限,目的就是让我们对多任务运行进行合理处理,提高系统运行效率

优先级

🖋️优先级查看

进程PCB信息中,还包含了这些信息:

  • UID 身份标识
  • PRI 进程优先级,默认为 80
  • NI 进程修正值,这个只有 Linux 中有,配合修改优先级,范围为 [-20, 19]

我们可以通过 ps 指令查看进程优先级情况

//注:其中的 myfile 是可执行程序名
$ ps -al | head -1 && ps -al | grep myfile	//查看进程优先级信息

查看进程优先级

🖋️优先级修改

进程优先级 可以被修改,但很少有人会主动修改

修改步骤

  • 输入 top 指令进入任务管理器
  • 输入 r 进入修改模式
  • 再根据想要修改的进程,输入 PID
  • 最后输入 NI 值,完成修改

优先级
注意:

  • NI值区间为 [-20, 19],设置时超出部分无效
  • 修改优先级时,最终优先级 = 初始优先级 + NI值,优先级的修改行为并不是连续的,每次都是在最开始的基础上进行修改(默认为 80)
  • 调度器不允许存在 优先级失衡 的情况,因此优先级修改不能太激进

📖进程特点

下面来简单小结一下进程的特点

  • 竞争性:CPU 资源有限,进程 间存在竞争
  • 独立性:进程 是相互独立运行的,互不干扰 (重要)
  • 并行:多个 进程 可以在多个 CPU 上同时运行
  • 并发:在一个 CPU 下采用 进程 切换的方式运行多个 进程

📘总结

以上就是有关进程学习【三】的全部内容了,本文主要研究对象是 环境变量,知道了 环境变量表 的存在,以及主函数是如何得到 环境变量表 表并实际运用的;最后还谈到了 进程优先级 问题,学习了优先级修改的相关指令;进程 最大的特性之一就是 独立性父子进程 间会发生 写时拷贝 机制,这种神奇的现象是如何产生的呢?敬请期待下篇中关于 进程地址空间 的相关文章

如果你觉得本文写的还不错的话,期待留下一个小小的赞👍,你的支持是我分享的最大动力!

如果本文有不足或错误的地方,随时欢迎指出,我会在第一时间改正


星辰大海

相关文章推荐

Linux进程学习【二】

Linux进程学习【一】

Linux工具学习之【gdb】

Linux工具学习之【git】

Linux工具学习之【gcc/g++】

Linux工具学习之【vim】

Linux 权限理解和学习

感谢支持

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Word控件Spire.Doc 【Table】教程(18):如何在 C# 中的 Word 中创建嵌套表格

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下&#xff0c;轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具&#xff0c;专注于创建、编辑、转…

「JVM 编译优化」即时编译器

前端编译器&#xff08;javac&#xff09;将 Java 代码转为字节码&#xff08;抽象语法树&#xff09;&#xff0c;优化手段主要用于提升程序的编码效率&#xff1b; 后端编译器&#xff08;内置于 JVM 的 JIT/AOT Compiler&#xff0c;C1&#xff0c;C2&#xff09;将字节码转…

2022年休闲游戏市场总结

在预测 2023 年之前&#xff0c;我们先回顾一下 2022 年。从上一年发生的事件中往往能看到未来趋势的影子&#xff0c;所以 2022 年的总结至关重要。一、2022年总结回顾1、流行游戏类型回顾 2022 年&#xff0c;三种超休闲游戏表现最为突出&#xff1a;跑酷游戏&#xff1a;跑酷…

spring之声明式事务开发

文章目录一、声明式事务之全注解式开发1、新建springConfig类2、测试程序3、测试结果二、声明式事务之XML实现方式1、配置步骤2、测试程序3、运行结果附一、声明式事务之全注解式开发 基于之前的银行转账系统&#xff0c;将spring.xml配置文件嘎掉&#xff0c;变成全注解式开发…

【极海APM32替代笔记】低功耗模式下的RTC唤醒(非闹钟唤醒,而是采用RTC_WAKEUPTIMER)

【极海APM32替代笔记】低功耗模式下的RTC唤醒&#xff08;非闹钟唤醒&#xff0c;而是采用RTC_WAKEUPTIMER&#xff09; 【STM32笔记】低功耗模式配置及避坑汇总 前文&#xff1a; blog.csdn.net/weixin_53403301/article/details/128216064 【STM32笔记】HAL库低功耗模式配置…

Spring Boot整合RabbitMQ教程

1.首页我们了解一下消息中间件的应用场景异步处理场景说明&#xff1a;用户注册后&#xff0c;需要发注册邮件和注册短信,传统的做法有两种1.串行的方式;2.并行的方式 (1)串行方式:将注册信息写入数据库后,发送注册邮件,再发送注册短信,以上三个任务全部完成后才返回给客户端。…

js实现轮播图

实现的效果图 原理:一次性加载所有图片&#xff0c;使用定位将图片重合在一起&#xff0c;根据opacity&#xff0c;z-index 属性显示当前图片 一、基本的HTML布局 创建一个外部容器来存放图片&#xff0c;prev-next是添加的左右切换按钮&#xff0c;dot存放图片下方的小白点…

《爆肝整理》保姆级系列教程python接口自动化(二十一)--unittest简介(详解)

简介 前边的随笔主要介绍的requests模块的有关知识个内容&#xff0c;接下来看一下python的单元测试框架unittest。熟悉 或者了解java 的小伙伴应该都清楚常见的单元测试框架 Junit 和 TestNG&#xff0c;这个招聘的需求上也是经常见到的。python 里面也有单元 测试框架-unitt…

小熊电器:精品与创意,走上“顶流之路”的两把“宝剑”

回顾2022年&#xff0c;小家电市场降温趋势明显&#xff0c;业绩表现整体低迷&#xff0c;如主打高端路线的北鼎&#xff0c;去年8亿元的营收出现个位数下滑&#xff0c;归母净利润同比下降超56%&#xff1b;苏泊尔营收也出现微降&#xff0c;归母净利润预计同比增长不到10%。而…

教你如何搭建培训机构-招生管理系统,demo可分享

1、简介1.1、案例简介本文将介绍&#xff0c;如何搭建培训机构-招生管理。1.2、应用场景根据意向信息站的收录信息&#xff0c;可批量导入意向信息&#xff0c;在意向信息站转为意向学员&#xff0c;转为意向学员后可进行报名收费成为正式学员。2、设置方法2.1、表单搭建1&…

从零实现深度学习框架:Seq2Seq从理论到实战【实战篇】

来源&#xff1a;投稿 作者&#xff1a;175 编辑&#xff1a;学姐 往期内容&#xff1a; 从零实现深度学习框架1&#xff1a;RNN从理论到实战&#xff08;理论篇&#xff09; 从零实现深度学习框架2&#xff1a;RNN从理论到实战&#xff08;实战篇&#xff09; 从零实现深度…

JUC-day01

JUC-day01 什么是JUC线程的状态: wait sleep关键字:同步锁 原理(重点)Lock接口: ReentrantLock(可重入锁)—>AQS CAS线程之间的通讯 1 什么是JUC 1.1 JUC简介 在Java中&#xff0c;线程部分是一个重点&#xff0c;本篇文章说的JUC也是关于线程的。JUC就是java.util .con…

活动预告 | GAIDC 全球人工智能开发者先锋大会

大会主题——“向光而行的 AI 开发者” 2023 全球人工智能开发者先锋大会&#xff08;GAIDC&#xff09; 由世界人工智能大会组委会、上海市经济和信息化委员会、上海市人才工作领导小组办公室及中国&#xff08;上海&#xff09;自由贸易试验区临港新片区管理委员会指导&…

【Java集合类】HashMap(二)- 设计要点

本章将开始探讨JDK中的HashMap&#xff0c;包括HashMap如何避免和解决上一章所说的散列冲突问题&#xff0c;以及Java 8对HashMap的改进 避免散列冲突- 散列函数设计 String.hashcode() Object.hashCode()方法用于返回当前对象的散列值。Object类中也约定了&#xff0c;重写…

【消费战略方法论】认识消费者的恒常原理(一):消费者稳态平衡原理

“消费战略”是塔望咨询基于大量的战略与营销实践经验结合心理学、经济学、传播学等相关专业学科的知识应用进行提炼与创造形成的战略方法体系。消费战略强调以消费者为导向&#xff0c;进行企业、品牌战略、品牌营销的制订和落地&#xff0c;企业经营的每个环节和输出的每个动…

提取括号中的内容

正则能解决不嵌套的括号内容提取问题遇到一个问题&#xff0c;就是需要提取字符串中每一个中括号里的内容&#xff0c;在网上搜了一下&#xff0c;发现用正则表达式(\[[^\]]*\])可以提取中括号中的内容&#xff0c;以下面文本为匹配对象&#xff1a;PerformanceManager[第1个中…

【算法基础】一维差分 + 二维差分

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;【C/C】算法 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵 希望大佬指点一二 如果文章对你有…

#笨鸟先飞 猴博士电路笔记 第一篇 电路基础

第零课 基础知识串联与并联电源电势与电位差第一课 电阻电路的等效变换电压源串联电流源并联电压源和电流源串联电压源和电流源并联电压源转化为电流源电流源转化为电压源Δ-Y等效变换第二课 基尔霍夫定律基尔霍夫电流定律任一结点上流出电流之和等于流入电流之和。受控电流源&…

Java 集合 --- 如何遍历Map

Java 集合 --- 如何遍历MapMap的基本操作如何遍历MapType of HashMapMap没有继承Collection接口AbstractMap和AbstractCollection是平级关系 Map的基本操作 package map; import java.util.*; /*** This program demonstrates the use of a map with key type String and val…

case的使用

1.x和z值 1.1.定义 x&#xff1a;表示不定值 z&#xff1a;表示高阻态&#xff0c;还有一种表达方式“&#xff1f;” 一个x/z可以用来定义十六进制&#xff08;h&#xff09;数的4位二进制的状态&#xff0c;八进制&#xff08;o&#xff09;数的3位&#xff0c;二进制&#x…