目录
进程的优先级
什么是优先级
优先级:指定进程获得某种资源的先后顺序。(优先级代表已经有相应的权限只不过获得资源的顺序不同)
linux中优先级数组越小,优先级越高
为什么要有优先级
进程访问的资源(CPU)始终是有限的--(因为只有一个cpu,如果有多个cpu那么相应的进程也会多都是类似的)而系统中进程大部分情况都是有较多的
操作系统关于调度和优先级的原则:分时操作系统(基于时间片来进行调度的) ,多个进程在被调度的时候保证基本的公平,如果进程长时间得不到cpu的调度就造成了饥饿问题。
linux的优先级特点和查看方式
使用ps -al命令
UID : 代表执行者的身份
PID : 代表这个进程的代号
PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
PRI :代表这个进程可被执行的优先级,其值越小越早被执行
NI :代表这个进程的nice值,进程优先级的修正数据,新的优先级=优先级+nice,达到对于进程优先级动态修改的过程。nice其取值范围是-20至19,一共40个级别
这样,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行,所以,调整进程优先级,在Linux下,就是调整进程nice值。需要强调一点的是,进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进 程的优先级变化
ps 命令在 Unix 和类 Unix 操作系统中用于显示当前系统的进程状态。ps -l 显示当前终端的进程的长格式信息,而 ps -al 显示系统上所有进程的长格式信息
用top命令更改已存在进程的nice:
top:
进入top后按“r”–>输入进程PID–>输入nice值:![]()
按r进入 ![]()
![]()
我输入nice值100但是最后显示19说明nice有范围
需要注意的是每次调整优先级每次都是从80开始的(PRI)![]()
其实top的pri是一个进程的相对优先级,top显示的跟ps显示的pri不一样;
top命令中的PR字段表示的是进程的相对优先级,这个值通常用来反映进程在调度中的相对重要性,数值越小表示优先级越高。它的计算可能会根据当前系统负载和调度策略进行动态调整。
显示的是进程的原始优先级,通常是静态的。这个值代表了进程在启动时的优先级或经过 nice 调整后的值。它通常基于进程的静态优先级,数值的范围和含义可能与 top 中的 PR 字段不同。
提到的这个80,是通过ps查询到的pri的值,他们两个是不一样的,pri字段显示的是进程的原始优先级,top中的PR字段是相对优先级。总结一下,top 显示的优先级是系统动态调整的相对值,而 ps 显示的是静态或经过调整的原始优先级。
其他概念
竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级
独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰
并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行
并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发
环境变量
命令行参数
在我们的主函数main中可带参也可不带,例如:
int main(int a,char*s[]),s是字符串数组,a是长度,main函数最多三个参数
int main()
#include<stdio.h>
#include<unistd.h>
int main(int a,char*s[]){
for(int i=0;i<a;i++){
printf("a[%d]: %s\n",i,s[i]);
}
return 0;
}
./mytest.exe -a -b -c叫做命令行字符串,第一个是程序的路径+可执行程序名后面叫做和该进程匹配的选项
为什么要有命令行参数?
本质:命令行参数本质是教给我们程序不同的选项,用来定制不同的程序功能。命令中带有很多的选项
就比如ls -l,ls-la等
命令行中启动的程序都会变成进程,其实都是bash进程的子进程,比如 ./mytest.exe是输入父进程bash的。因为bash进程就是命令行解释器
环境变量
查看环境变量方法
echo $NAME //NAME:你的环境变量名称
系统中有很多的配置,在我们登录Linux中时已经被加载到bash进程中(内存)
为什么我们平常输入ls/pwd就行,而到我们得./xx.exe -x呢?
这是因为在Linux中存在一些全局变量,表明告诉命令行解释器应该去哪些途径下去寻找可执行程序。当然你也可以将自己的程序cp到指定的path下这样就不用./了但是不建议![]()
添加方式
root@wwz:~# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin在我的
PATH
环境变量中列出了多个目录,这些目录是系统用来寻找可执行文件的路径。当你在命令行中输入一个命令时,系统会按照PATH
中的目录顺序查找对应的可执行文件。当你在命令行中输入一个命令时,系统会按照
PATH
中的目录顺序查找该命令对应的可执行文件。如果一个目录中存在该命令的可执行文件,系统将执行它;如果找不到,系统将继续查找下一个目录。如果系统在
PATH
中指定的所有目录中都找不到你输入的命令,通常会显示以下错误信息:bash: <command>: command not found
/usr/bin 目录下主要存放用户级的可执行文件,但它不只包含可执行文件,还可能包含一些符号链接和脚本。这个目录通常用于存放系统默认安装的应用程序和工具,例如:
用户命令: 各种系统工具和应用程序,如 ls, grep, find, python。
符号链接: 指向其他位置的可执行文件或脚本。
脚本: 包含可执行脚本文件,这些脚本通常以 #!/bin/sh 或类似的 shebang 行开头,用于指定解释器。
虽然 /usr/bin 主要用于存放可执行文件,但它的确也可能包含一些脚本文件和符号链接。那么我在/usr/bin目录下使用ls和./ls效果是一样的;
在这种情况下,两者都指向同一个可执行文件,并执行相同的操作。区别在于,./ 用于指示执行文件的确切路径(在当前目录),而 ls 只要在 PATH 中的目录中找到对应的文件就可以执行。
修改PATH
对PATH修改:
1.直接覆盖修改,可能导致一些命令不能用,如果能跑说明不需要这个环境变量
这时候重新进入xshell进行,因为PATH是进入的时候加载到内存中的,自己有配置文件2.追加,PTAH=$PATH:XXXX XXX是追加的途径
这样就跟ls等命令一样不用加./了再重新登录也会初始化说明最开始的环境变量不是在内存中,而是在系统的对应的配置文件中
如果想一直保存则要修改配置文件

那么有一个问题?为什么我们安装java或者python都要我们安装环境变量,这是为什么呢?
主要原因是想通过环境变量直接找到我的可执行程序,不要让我带路径执行这样麻烦,并且可以让其他程序或脚本能够轻松地调用 Java 或 Python 程序。
其他环境变量
env:显示所有环境变量
export: 设置一个新的环境变量 export name=xxxx

unset: 清除环境变量 unset name
理解environ:
可以看到环境变量可以被子进程拿到,说明环境变量不在子进程里,那么他在那里?默认在bash内部里。父进程的数据默认能被子进程看到并访问。extern char **environ; 是一个指向指针的指针,其中每个 char * 指针指向一个环境变量的字符串。在 C/C++ 中,二维数组(例如 char *argv[])通常使用 char ** 来表示。
bash进程启动的时候,默认会给我子进程形成两张表:
argv[]命令行参数表(就是主函数main里的参数main(int a,char*argv[])),env[]环境变量表(从os的配置文件获得),bash通过各种方式交给子进程

比如export一个环境变量就是添加到env[]表里
理解:环境变量具有系统级的全局属性,因为环境变量本身会被子进程继承下去
同样也可以这样获得环境变量:
getenv("xxx");----需要的环境变量name需要stdlib.h头文件
本地变量(即只在当前 shell 会话中有效的变量)只在本bash内部有效,无法被子进程继承下去,如果需要将变量传递给子进程,可以通过将本地变量导出为环境变量来实现,此时才能够被获取
如下就是一个本地变量:
新建终端:发现不能打印本地变量
echo export都是内建命令 不是子进程;
内建命令是 shell(例如 Bash)内置的命令,这些命令直接由 shell 提供,不需要调用外部程序或脚本。它们通常用于执行基本的操作和管理 shell 环境。内建命令的执行速度较快,因为它们不需要启动额外的进程。
内建命令(built-in commands)是由 shell 直接实现的,不需要新建子进程来执行。
常见的内建命令包括:cd:改变当前工作目录。
echo:输出文本到标准输出。
export:设置环境变量。
pwd:显示当前工作目录。
alias:定义命令别名。
unset:删除变量或函数。这些命令在 shell 启动时就被加载,并且在整个 shell 会话中可用。
内建命令相对的是外部命令,这些命令通常是存储在文件系统中的可执行程序或脚本,需要由 shell 启动一个新的进程来执行。
当你运行外部命令时,shell 会启动一个新的进程来执行它。
这通常包括以下步骤:
查找命令:shell 根据环境变量 PATH 查找外部命令的位置。
创建进程:shell 使用 fork 系统调用创建一个新的子进程。
执行命令:新创建的子进程使用 exec 系统调用加载和执行外部命令。
等待完成:shell 会等待子进程执行完成,并处理其退出状态。