【Linux系统编程】第二十弹---进程优先级 命令行参数 环境变量

个人主页: 熬夜学编程的小林

💗系列专栏: 【C语言详解】 【数据结构详解】【C++详解】【Linux系统编程】

目录

1、进程优先级

2.1、什么是优先级

2.2、优先级的描述

2.3、优先级与权限的关系

2.4、为什么要有优先级

2.5、Linux优先级的特点

2.6、其他概念

2、命令行参数

3、环境变量

3.1、基本概念

3.2、PATH环境变量

3.3、其他环境变量


1、进程优先级

2.1、什么是优先级

指定进程获取某种资源(CPU)的先后顺序。

2.2、优先级的描述

进程优先级的描述跟进程状态描述类似,实质是在task_struct(内存控制块)结构体内部有一个描述优先级的属性,通过数字表示先后顺序。Linux 中优先级数字越小,优先级越高。

2.3、优先级与权限的关系

权限决定能不能获取资源。

优先级决定获取资源的顺序,已经能获取资源。

2.4、为什么要有优先级

进程访问的资源(CPU)始终是有限的。系统中进程大部分情况都是比较多的。

操作系统关于调度和优先级的原则:分时操作系统,基于时间片进行调度,保证基本的公平。如果进程因为长时间不被调度,就造成了饥饿问题。

2.5、Linux优先级的特点

在讲解优先级特点之前,我们先通过一个C语言程序查看优先级。

C语言代码

#include<stdio.h>
#include<unistd.h>int main()
{while(1){printf("I am a process,pid:%d\n",getpid());}return 0;
}

 命令行代码

ps -al // 查看所有进程信息

测试结果 

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

UID : 代表执行者的身份。
PID : 代表这个进程的代号。
PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号。
PRI :代表这个进程可被执行的优先级,其值越小越早被执行。
NI :代表这个进程优先级的修正数据,nice值,新的优先级 = 默认优先级 + nice,达到对于进程优先级动态修改的过程。

调整优先级

nice/renice 调整优先级

此处博主使用top命令调整优先级。

  • 输入top命令
  • 进入top后按“r”–>输入进程PID–>输入nice值

测试一 

我们将nice值改为100,现象如下:

可以看到 NI 只修改为了19,PRI修改为了99。表名nice值并不能任意调整,而是有范围的。 范围是 [-20,19] ,共40个数字。

测试二

我们将nice值改为-10,现象如下:

我们可以看到,当我们第二次修改nice值时,不允许我们修改,因为修改优先级是有风险的,如果强制需要修改nice值,我们只需要切换成root账号即可。 

测试三

使用root账号将nice值改为-10,现象如下:

我们可以看到NI修改成了-10,PRI修改成了70,我们刚刚的PRI是99,将nice值修改为-10,为什么现在的PRI为70了呢?原因是 每次调整优先级都是从80开始的。新的优先级 = 默认优先级 + nice,70 = 80 - 10。

测试四

使用root账号将nice值改为-100,现象如下:

可以看到NI被修改为-20,因此能够证明nice的最小值为-20,且新的优先级 = 默认优先级 + nice,60 = 80 - 20。

2.6、其他概念

  • 竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级。
  • 独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰。
  • 并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行。
  • 并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发。

2、命令行参数

写C语言代码中,main函数也是函数,可以带参数?

答案是可以带参数也可以不带参数,下面就使用带参数的main函数演示。

代码演示

#include<stdio.h>// 命令行参数测试
int main(int argc,char* argv[])
{int i = 0;for(i=0;i<argc;i++){printf("argv[%d] = %s\n",i,argv[i]);}return 0;
}

 测试结果

通过上图现象我们可以看到argc是元素个数,argv是一个边长数组,猜测数组以NULL结尾。 

验证数组以NULL结尾

#include<stdio.h>int main(int argc,char* argv[])
{int i = 0;// argv[i]为假则循环结束for(i=0;argv[i];i++){printf("argv[%d] = %s\n",i,argv[i]);}return 0;
}

测试结果 

为什么要有命令行参数?

本质:命令行参数本质是交给我们程序的不同选项,用来定制不同的程序功能。命令中会携带很多选项。

命令行中启动的程序是谁干的?

命令行中启动的程序,都会变成进程,且都是bash的子进程,因此是bash(命令行解释器)干的。

代码演示一

#include<stdio.h>
#include<unistd.h>int g_val = 10000;
int main()
{printf("I am parent process,g_val:%d,pid:%d,ppid:%d\n",g_val,getpid(),getppid());sleep(5);pid_t id = fork();if(id == 0){while(1){printf("I am child process,g_val:%d,pid:%d,ppid:%d\n",g_val,getpid(),getppid());sleep(1);}}else{printf("I am parent process,g_val:%d,pid:%d,ppid:%d\n",g_val,getpid(),getppid());sleep(1);}return 0;
}

父进程的数据,默认能被子进程看到并访问。

代码演示二

#include<stdio.h>
#include<unistd.h>
#include<string.h>int g_val = 10000;
int main(int argc,char* argv[])
{printf("I am parent process,g_val:%d,pid:%d,ppid:%d\n",g_val,getpid(),getppid());if(argc != 2){printf("Usage: %s -[a,b,c,d]\n", argv[0]);return 1;}if(strcmp(argv[1], "-a") == 0){printf("this is function1\n");}else if(strcmp(argv[1], "-b") == 0){printf("this is function2\n");}else if(strcmp(argv[1], "-c") == 0){printf("this is function3\n");}else if(strcmp(argv[1], "-d") == 0){printf("this is function4\n");}else{printf("no this function!!\n");}return 0;
}

测试结果 

命令行中启动的程序,都会变成进程,且都是bash的子进程。启动程序,默认是输入给父进程bash(命令行解释器)的!!!

3、环境变量

3.1、基本概念

  • 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数。
  • 如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
  • 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性。

3.2、PATH环境变量

基本认知

执行命令和运行自己写的程序是没有区别的,且Linux中70% 的命令是C语言写的。

为什么执行ls这些系统提供的命令可以不带路径,而我们自己写的C语言程序需要加./(带路径)呢?

Linux系统重存在一些全局的设置,表明告诉命令行解释器应该去哪个路径下去寻找可执行程序,当执行ls命令(可执行程序在/usr/bin目录中)时,会先去找ls对应的可执行程序,默认去PATH中找。

查看PATH内容 

 通过echo $PATH 获取PATH(环境变量)内容 ,类似*p。

补充:

  • 系统中很多的配置,在我们登录Linux系统的时候,已经被加载到了bash进程中(内存)。
  • bash在执行命令的时候,需要先找到路径(默认去PATH中找),因为未来要加载。

如果我们想像系统指令一样执行自己写的可执行程序,怎么做?

方式一(粗暴):直接将我们的可执行程序拷贝到PATH的其中一个路径(例如/usr/bin)中。

注意:拷贝内容到PATH环境中需要配root权限,此处使用sudo提权。

sudo cp myprocess /usr/bin  # 此处的/usr/bin也可以是PATH中的其他路径

 不建议使用这种方式,因此下面我们将该可执行程序在/usr/bin中的内容删除。

sudo rm /usr/bin/myprocess

方式二(温柔):把可执行程序路径增加到PATH环境变量中。

错误示范:

PATH=/home/jkl/path # 将可执行程序的当前目录赋值给PATH变量,会直接覆盖PATH

环境变量直接被我们新的路径覆盖了怎么办呢?

其实很简单,直接将系统关闭,重进系统就可以了。因为我们上面说了 系统中很多的配置,在我们登录Linux系统的时候,已经被加载到了bash进程中(内存)

我们重新登录系统之后,发现环境变量回来了,且不能直接执行我们写的可执行程序了。

 正确示范:

PATH=$PATH:/home/jkl/path # 将原本的PATH路径以及我们可执行程序当前目录赋值给PATH

 演示结果

PATH环境变量是Linux系统中搜索可执行程序的默认路径,也是which指令搜索路径的默认路径。

PATH环境变量的路径是内存级别的,重新登录系统又会变成默认路径,怎样让追加的环境变量路径永久存在呢?

最开始的环境变量不是在内存中,而是在系统对应的配置文件中,在我们登录系统时,会创建一个bash进程,bash进程会读取配置文件,然后把配置文件的环境变量(包括PATH)在自己的bash进程拷贝一份。

这个配置文件在哪里?

vim .bash_profile
vim .bashrc
vim /etc/bashrc

我们的PATH配置文件可能在.bash_profile或者.bashrc中。博主的在.bashrc中。

想要登录时每次都默认执行自己写的可执行程序,把可执行程序路径加到环境变量的配置文件里面即可,如下图:

加上该路径之后,myprocess可以像系统命令(ls)一样,在任意目录中使用了,且无需加./。 

Windows也有环境变量,我们在安装jdk或者python时一般需要配置环境变量。

3.3、其他环境变量

env : 查看系统所有的环境变量

history :查看历史命令

HOME : 家目录所在的环境变量

PWD : 当前目录路径变化

SHELL :  当前Shell,它的值通常是/bin/bash。

HISTSIZE : 历史命令个数 上翻下翻 Linux默认会记录最新的1000条命令

自己定义一个环境变量:

export THIS_IS_MY_ENV=hellolinux   导入环境变量(不加export,依旧存在变量,本地变量)

unset THIS_IS_MY_ENV  取消环境变量

export测试

疑问:export 也是一个命令,命令就会创建子进程,子进程就应该不被bash看到,为什么却能将变量导入到环境变量中。?

80% 命令都是bash创建子进程执行的 ,称为普通命令。还有20%命令,如(export / echo) 由bash亲自执行的,称为内建命令

怎么证明真的有内建命令呢?

通过上面实验,我们可以证明确实有内建命令。 

普通测试 

  • 本地变量只在bash内部有效,无法被子进程继承下去。导成环境变量才能被获取。
  • 用本地变量理解内建命令。内建命令可以查到本地变量。
  • echo能够打印本地变量(子进程无法获取)也能够证明echo是内建命令。

注意:已经存在的本地变量导成环境变量,只需要使用export 变量名即可。

能否通过C语言程序查看环境变量呢?

答案是可以的,在写程序之前我们需要查一下手册,man environ,environ为查看全局的指针变量。

C语言程序

#include<stdio.h>
#include<unistd.h>
int main()
{extern char** environ;// 声明外部文件变量int i=0;for(i=0;environ[i];i++)// environ[i]为假则循环结束{printf("env[%d]->%s\n",i,environ[i]);}return 0;
}

测试结果 

测试结果与使用命令env的结果是一样的。 说明环境变量默认也是可以被bash子进程拿到的。环境变量们,默认在bash内部。

环境变量有很多,bash内部是如何组织的?

通过上面的C语言代码我们大概可以推断,环境变量的组织与命令行参数类似,是通过一个变长数组组织的,最后一个数据以NULL结尾。

main函数带参的C语言程序

#include<stdio.h>
#include<unistd.h>
int main(int argc,char* argv[],char* env[])
{int i = 0;for(i=0;env[i];i++){printf("env[%d]->%s\n",i,env[i]);}return 0;
}

测试结果 

bash进程启动的时候,默认会给子进程形成argv[]命令行参数表(用户输入的命令行来),env[]环境变量表(从OS的配置文件来),bash通过各种方式交给子进程。

补充:

  • 导环境变量的本质:把字符串添加到环境变量表中。
  • 环境变量具有系统级的全局属性,因为环境变量会被子进程继承下去。

获取环境变量方法:

  • extern char** environ;
  • main函数参数
  • getenv("path");
man getenv

代码 

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main(int argc,char* argv[],char* env[])
{char* path = getenv("PATH");if(path == NULL) return 1;printf("psth:%s\n",path);return 0;
}

测试结果 

putenv(); // 创建环境变量

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

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

相关文章

某oa命令执行漏洞挖掘思路

《网安面试指南》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484339&idx1&sn356300f169de74e7a778b04bfbbbd0ab&chksmc0e47aeff793f3f9a5f7abcfa57695e8944e52bca2de2c7a3eb1aecb3c1e6b9cb6abe509d51f&scene21#wechat_redirect 《Java代码审…

图像修复(Inpainting)技术的前沿模型与数据集资源汇总

图像修复&#xff08;Image Inpainting&#xff09;是一种计算机视觉技术&#xff0c;旨在填补图像中的缺失区域或去除图像中的不需要部分&#xff0c;使其看起来自然且无明显痕迹。其目标是根据图像的上下文信息和周围像素来推断和重建缺失区域的内容&#xff0c;以生成逼真且…

《机器学习》周志华-CH7(贝叶斯分类)

7.1贝叶斯决策论 对分类任务而言&#xff0c;在所有相关概率已知的理想情形下&#xff0c;贝叶斯决策论考虑如何基于这些概率核误判损失来选择最优的类别标记。 R ( x i ∣ x ) ∑ j 1 N λ i j P ( c j ∣ x ) \begin{equation} R(x_{i}|x)\sum_{j1}^{N}\lambda_{ij}P(c_{j}…

DTMF2str集成工具

DTMF2str 项目地址&#xff1a; baicaiyihao/DTMF2str: DTMF解码并转换为字符串 (github.com) 用于CTF中misc DTMF题中&#xff0c;方便ctfer解题。 注&#xff1a;工具根据现有的一些题型进行编写的&#xff0c;如果有无法解出的题型可以提issus后续进行完善。 工具功能&a…

C++独立开发开源大数计算库 CBigNum

项目简介&项目地址 CBigNum 是本人独立开发开源的一款大数计算库&#xff0c;支持任意位数整数带任意位数小数的浮点运算。您可以通过本库执行非常大的数据运算或非常高精度的除法运算(您可以随意指定除法的小数保留到第几位)。 项目地址&#xff1a;https://github.com/…

MATLAB路径规划如何采用矢量法让他们尽量在一个方向??

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

HTML | 外部引入 CSS 的2种方式:link和@import有什么区别?

外部引入 CSS 有2种方式&#xff0c;link 和 import。就结论而言&#xff0c;强烈建议使用 link &#xff0c;慎用 import 方式。 两者都是外部引用 CSS 的方式&#xff0c;但是存在一定的区别&#xff1a; &#xff08;1&#xff09;从属关系区别 link是HTML / XHTML标签&a…

误删分区后的数据救赎恢复实战解析

在数字化时代&#xff0c;数据不仅是信息的载体&#xff0c;更是个人记忆与企业资产的宝贵财富。然而&#xff0c;误删分区这一操作失误&#xff0c;却如同暗流涌动&#xff0c;悄无声息地吞噬着用户的重要数据。本文将深入探讨误删分区的现象、影响&#xff0c;并详细介绍一种…

Linux运维培训班靠谱吗?如何判断一个培训班的教学质量?

当我们下定决心打算系统培训Linux运维时&#xff0c;哪家机构比较好成为了我们面临的最大难题。之前分享过很多培训机构的个人感受&#xff0c;但授人以鱼不如授人以渔&#xff0c;说到底那些都是我个人的看法&#xff0c;因此今天打算帮助大家学会如何判断一个培训班的好坏。 …

C# 修改项目类型 应用程序程序改类库

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…

72、Python之函数式编程:纯函数与lambda表达式

引言 今天聊点简单的&#xff0c;也就是“纯函数”。任何一个函数只要满足纯函数的两个特性&#xff0c;就是纯函数。纯函数与lambda表达式&#xff0c;其实没有必然的联系。只是由于lmbada表达式比较简洁&#xff0c;很多时候可以作为纯函数的一种实现方式。 本文的主要内容…

PointNet++改进策略目录

后续我将如何使用文章中创新点加入的PointNet中代码实现部分进行更新 题目原理解析代码改进PointNet改进策略 &#xff1a;模块改进 | LFA | RandLA-Net&#xff0c;通过随机采样与局部特征聚合提升大规模3D点云处理效率✔️❌PointNet改进策略 &#xff1a;模块改进 | Residua…

【网络】详解HTTP协议的CGI机制和CGI进程

目录 引言 CGI机制模型 伪代码示例 个人主页&#xff1a;东洛的克莱斯韦克-CSDN博客 引言 CGI机制是HTTP协议提供的偏底层的一套机制&#xff0c;也是非常重要的机制——它让大量的业务进程和HTPP协议解耦。而CGI进程是业务层的&#xff0c;用来处理各种数据&#xff0c;比…

1分钟解锁AI绘本财富密码:从0到10万粉,她只用了三步!

在这个信息爆炸的时代&#xff0c;我们每天都在为生活奔波&#xff0c;赚钱似乎变得越来越难。记得小时候&#xff0c;我们总是梦想着能有一种魔法&#xff0c;让书本里的金币自动飞入脑中&#xff0c;但现实却是残酷的我们只能眼睁睁地看着那些遥不可及的梦想。然而&#xff0…

Selenium with Python学习笔记整理(网课+网站)

本篇是根据学习网站和网课结合自己做的学习笔记&#xff0c;后续会一边学习一边补齐和整理笔记 官方学习网站在这获取&#xff1a; https://selenium-python.readthedocs.io/getting-started.html#simple-usage WEB UI自动化环境配置 (推荐靠谱的博客文章来进行环境配置,具…

再次被对地观测拒稿

又拒稿了&#xff0c;这次应该不是没法修改了&#xff0c;范围不一样&#xff0c;准备改投其他期刊了。 创新性不够说明还难以达到1区的要求&#xff0c;继续先投着一区试试吧&#xff0c;不行再降了 所以说还需要一开始就对照期刊范围来写&#xff0c;比较有针对性。

apk反编译修改教程系列-----修改apk 去除软件加固状态 应用加固的一些常识与检测【二十六】

目前很多apk应用有加固。其中包括如360加固、腾讯乐固等,厂商无非是把一系列的混淆、加密、隐藏、检测等技术组合起来,封装好给你使用。真实的目的就是防止APK被调试 。呗任意修改。此博文普及一些加固的基本常识。后续实例演示一些apk去加固的步骤。 通过博文了解 1-----a…

OpenAI的o1模型与Transformer的无限潜力:数学证明推理算力无上限

近期&#xff0c;斯隆奖得主马腾宇和Google Brain推理团队创始人Denny Zhou合作&#xff0c;提出了一项引人注目的数学证明&#xff1a;只要思维链&#xff08;CoT&#xff09;足够长&#xff0c;Transformer就有能力解决各种复杂问题。这一发现引发了广泛关注&#xff0c;因为…

智能BI项目第三期

AIGC AI 提问技巧 为了让 Al 更好地理解我们的输入&#xff0c;并给出预期精确的输出&#xff0c;需要严格控制我们的提问词。 1.使用系统预设 控制输入格式(便于Al精确地理解我们的需求) 你是一个数据分析师和前端开发专家&#xff0c;接下来我会按照以下固定格式给你提供…

【开源免费】基于SpringBoot+Vue.JS在线文档管理系统(JAVA毕业设计)

本文项目编号 T 038 &#xff0c;文末自助获取源码 \color{red}{T038&#xff0c;文末自助获取源码} T038&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…