文章目录
- Linux优先级
- Linux的调度与切换
- **进程切换**:
- **进程调度**:
- 优先级
- 活动队列
- 过期队列
- active指针和expired指针
- 环境变量
- main函数参数 `int main(int argc, char *argv[], char *envp[]) `
- 环境变量
- 环境变量和本地变量
- `echo`查看单个环境变量的方法
- `export`添加路径到环境变量PATH
- `export`设置环境变量
- `set`和`export`设置环境变量
- `set`显示本地定义的shell变量和环境变量
- `env`显示环境变量
- `unset`删除环境变量或本地变量
- 环境变量的组织方式
- 通过代码如何获取环境变量
- 1. 命令行第三个参数(`main`函数第三个参数)
- 2. 通过第三方变量`environ`获取
- 3. `getenv()`获取指定名称的环境变量的值
- 环境变量通常是具有全局属性的
- `bash_profile`文件
- 先有命令参数表,再有环境变量表
- 先有命令参数表,再有环境变量表
Linux优先级
Linux默认优先级是80. Linux的优先级是可以被修改的,Linux可被修改的优先级的范围是**[60,99],因为nice的值为[-20,19]** 数字越小,优先级越高
Linux系统允许用户调整优先级,但是不是直接修改pri,而是修改nice值。 pri=pri(old)+nice
修改进程优先级方法:输入top->输入r->输入pid->输入nice的改变值
Linux为什么调整优先级是要受限制的?
如果不加限制,将自己进程的优先级调整的非常高,别人的进程可以调整的非常低。优先级较高的进程,优先得到资源,后续还有源源不断地进程产生,常规进程很难享受到CPU资源,会产生进程饥饿问题。
Linux的调度与切换
进程切换:
进程在运行的过程中,要产生大量的临时数据,放在CPU的寄存器中!CPU内部的所有的临时数据,我们叫做进程的硬件上下文。
进程下CPU时我们的进程进行保存硬件上下文,以保护上下文。
当进程在第二次被调度的时候,进程被放到CPU上开始运行,将曾经保存的硬件上下文进行恢复。
虽然寄存器数据放在了一个共享的CPU设备里面,但是所有的数据其实都是被进程私有的。
进程调度:
O(1)调度算法
Linux2.6内核中进程队列的数据结构:
一个CPU拥有一个runqueue,一个runqueue有多个优先级队列
优先级
-
普通优先级:100~139(我们都是普通的优先级,[60 ~ 99] ,nice的取值范围 [-20~19] 是与之相对应的,映射)
-
实时优先级:0~99
活动队列
-
时间片还没结束的所有进程都按照优先级放在该队列
-
nr_active:总共有多少个运行状态的进程
-
queue[140]:一个元素就是一个进程队列,相同优先级的进程按照FIFO规则进行排队调度,所以数组下标就是优先级
-
从该结构中,选择一个最合适的进程,过程是怎么的呢?
-
从0下表开始遍历queue[140]
-
找到第一个非空队列,该队列必定为优先级最高的队列
-
拿到选中队列的第一个进程,开始运行,调度完成!
-
遍历queue[140]时间复杂度是常数!但还是太低效了!
-
-
bitmap[5]:一共140个优先级,一共140个进程队列,为了提高查找非空队列的效率,就可以用5*32个 比特位表示队列是否为空,这样,便可以大大提高查找效率!
过期队列
- 过期队列和活动队列结构一模一样
- 过期队列上放置的进程,都是时间片耗尽的进程或新来的进程
- 当活动队列上的进程都被处理完毕之后,对过期队列的进程进行时间片重新计算
active指针和expired指针
- active指针永远指向活动队列
- expired指针永远指向过期队列
- 可是活动队列上的进程会越来越少,过期队列上的进程会越来越多,因为进程时间片到期时一直都存在的。
- 但是在合适的时候,只要交换active指针和expired指针的内容,就相当于具有了一批新的活动进程
环境变量
main函数参数 int main(int argc, char *argv[], char *envp[])
argc
和 argv[]
、envp[]
是 C 语言中 main()
函数的参数,用于处理命令行参数。
argc
是一个整数,表示命令行参数的数量,包括程序名称本身。它至少为 1,因为第一个参数始终是程序的名称(通常是可执行文件的路径)。argv
是一个指向字符指针数组的指针,它包含了命令行参数的实际内容。argv[0]
存储的是程序的名称,argv[1]
到argv[argc-1]
存储的是命令行中给定的参数。envp
是一个指向字符指针数组的指针,其中每个元素都是一个指向环境变量字符串的指针。每个环境变量的格式是name=value
,例如PATH=/usr/bin
。这个参数通常用于访问程序的环境变量。这些环境变量通常由操作系统传递给程序,用于提供关于运行环境的信息。
下面是一个简单的示例,演示如何使用 argc
和 argv[]
处理命令行参数:
cCopy code解释#include <stdio.h>int main(int argc, char *argv[]) {int i;// 打印程序名称printf("Program name: %s\n", argv[0]);// 打印命令行参数printf("Number of arguments: %d\n", argc - 1);for (i = 1; i < argc; i++) {printf("Argument %d: %s\n", i, argv[i]);}return 0;
}
假设你将上述程序保存为 command_line.c
,然后编译并运行它。当你在命令行中执行该程序时,可以给它传递一些参数。例如:
./command_line arg1 arg2 arg3
在这个例子中,程序会输出以下内容:
Program name: ./command_line
Number of arguments: 3
Argument 1: arg1
Argument 2: arg2
Argument 3: arg3
这里,argc
的值是 4,因为有 4 个参数(包括程序名称),而argv[]
包含了这些参数的实际值。
环境变量
环境变量是操作系统中用来存储系统配置信息和进程运行环境的一种机制。在大多数操作系统中,包括Unix/Linux和Windows,环境变量都是以键值对的形式存在的。
一些基本概念包括:
- 环境变量名称:每个环境变量都有一个名称,用于唯一标识该变量。例如,"PATH"是一个常见的环境变量名称,用于指定可执行程序的搜索路径。
- 环境变量的取值:与每个环境变量名称关联的是一个取值,表示该变量当前的设置值。例如,"PATH"环境变量的取值可能是一串以冒号分隔的路径列表。
- 设置环境变量:可以通过操作系统提供的工具或命令来设置环境变量。在Unix/Linux系统中,可以使用
export
命令;在Windows系统中,可以使用set
命令。 - 使用和获取环境变量:程序可以通过读取环境变量来获取系统配置信息或自定义设置。程序可以通过环境变量接口读取已经设置的环境变量。在C语言中,可以使用
getenv()
函数来获取特定环境变量的取值。 - 常见环境变量:一些常见的环境变量包括PATH(指定可执行程序的搜索路径)、HOME(当前用户的主目录路径)、USER(当前用户名)、PWD(指向当前工作目录的路径)等。
环境变量在操作系统中起着重要的作用,可以提供灵活的配置和运行环境设置,方便程序之间共享信息和系统管理。
环境变量和本地变量
环境变量和本地变量是计算机科学中两个重要的概念,它们在编程和系统管理中起着不同的作用。
-
环境变量(Environment Variables):
- 环境变量是在操作系统级别定义的一种变量,可被所有在该操作系统上运行的程序所访问。
- 环境变量通常包含了一些系统范围内的配置信息,例如路径、语言偏好、临时文件夹等。
- 环境变量在操作系统启动时被加载,并且可以在系统的整个生命周期内保持不变,除非被显式修改。
- 在大多数操作系统中,可以通过命令行工具或配置文件来设置和管理环境变量。
-
本地变量(Local Variables):
- 本地变量是在程序或函数内部定义的变量,只在定义它们的作用域内可见和可访问。
- 本地变量的作用域通常由它们所在的代码块(例如函数、循环、条件语句等)决定。
- 当程序执行离开该变量所在的作用域时,本地变量通常会被销毁,释放所占用的内存空间。
- 本地变量通常用于存储临时数据、函数参数以及在函数内部进行计算等临时性任务。
虽然环境变量和本地变量在概念上有所不同,但它们都是在程序执行过程中用来存储和操作数据的方式。在编程中,理解并正确使用这两种变量类型是非常重要的。
echo
查看单个环境变量的方法
echo $NAME
//NAME:你的环境变量名称
例如:echo $PATH
echo $PATH
是一条在 Unix/Linux 系统中查看环境变量 PATH
的命令。在 Unix/Linux 系统中,$PATH
是一个特殊的环境变量,用于指定系统在哪些目录中搜索可执行文件。
当您在终端中执行 echo $PATH
时,系统会将 $PATH
替换为实际的环境变量值,并将其输出到终端上。这个值通常是一系列由冒号分隔的目录路径。示例输出可能如下所示:
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/liuxu/.local/bin:/home/liuxu/bin
这表示系统会按照列出的顺序依次搜索这些目录,以查找用户输入的命令对应的可执行文件。
export
添加路径到环境变量PATH
export PATH=/new/path/to/add:$PATH
注意 $PATH
表示当前 PATH
的值,这样可以确保您添加的路径位于现有路径之前,这样新的路径会优先于之前的路径进行搜索。
export
设置环境变量
在 Linux 中,export
是一个命令用于将变量声明为环境变量,使得该变量对当前 shell 进程及其子进程可见。export
命令通常用于设置全局的环境变量。以下是 export
命令的基本用法:
将变量导出为环境变量:
如果要将一个变量声明为环境变量,可以使用 export
命令。例如,假设有一个名为 MY_VARIABLE
的变量,要将其设置为环境变量,可以执行以下命令:
export MY_VARIABLE=value
这个命令将 MY_VARIABLE
设置为 value
并将其导出为环境变量,使得它对当前 shell 进程及其子进程可见。
set
和export
设置环境变量
在Linux中,set variable_name=value
和export variable_name=value
都是用来设置环境变量的方法,但它们之间存在一些区别:
-
set variable_name=value
:- 这种形式的设置仅在当前shell中有效,不会将变量传递给后续的子shell。
- 变量只在当前shell中可见,对于子shell或其他进程来说是不可见的。
-
export variable_name=value
:- 使用
export
命令设置的变量会被导出到当前shell及其所有后续的子shell。 - 这意味着子shell及其衍生进程(例如通过当前shell启动的脚本)都能够访问和使用这些变量。
- 通过
export
导出的变量在当前shell退出后仍然有效,直到显示地使用unset
命令将其删除或重新设置。
- 使用
例如,假设你想设置一个环境变量MY_VAR
为hello
,然后在子shell中运行一个脚本。下面是两种方法的对比:
使用set
命令:
set MY_VAR=hello
./my_script.sh
在my_script.sh
中,$MY_VAR
可能是未定义的,因为set
设置的变量不会自动传递给子shell。
使用export
命令:
export MY_VAR=hello
./my_script.sh
在my_script.sh
中,$MY_VAR
将会是hello
,因为export
命令导出的变量会传递给子shell。
set
显示本地定义的shell变量和环境变量
set
env
显示环境变量
在Linux中,env
是一个命令行实用程序,用于显示当前环境中已设置的所有环境变量,或者在指定环境下执行给定的命令。
显示当前环境变量:
如果不带任何参数运行 env
命令,则会显示当前 shell 进程中的所有环境变量及其值。示例:
env
这个命令会列出当前 shell 进程中定义的所有环境变量及其值。
unset
删除环境变量或本地变量
在 Linux 命令行环境中,可以使用 unset
命令来删除一个或多个环境变量。unset
命令会将指定的变量从当前 shell 进程中移除,使得它在当前 shell 及其子进程中不再可用。
unset VAR_NAME
这个命令会从当前 shell 进程中移除名为 VAR_NAME
的环境变量。如果要删除多个环境变量,可以将它们依次列出,用空格分隔。
环境变量的组织方式
每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串
通过代码如何获取环境变量
1. 命令行第三个参数(main
函数第三个参数)
#include <stdio.h>
int main(int argc, char *argv[], char *env[])
{int i = 0;for(; env[i]; i++){printf("%s\n", env[i]);}return 0;
}
2. 通过第三方变量environ
获取
#include <stdio.h>
#include <stdlib.h>// 声明全局变量 environ,存储环境变量
extern char **environ;// 主函数,接受命令行参数 argc 和 argv
int main(int argc, char *argv[]) {// 创建指向环境变量字符串数组的指针char **env = environ;// 打印环境变量信息的标题printf("Environment variables:\n");// 遍历环境变量数组,并打印每个环境变量while (*env != NULL) {printf("%s\n", *env);env++;}return 0;
}
//定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时 要用extern声明。
3. getenv()
获取指定名称的环境变量的值
getenv() 是 C 标准库中的一个函数,用于从环境中获取指定名称的环境变量的值。
它的声明和用法如下:
声明:
char* getenv(const char* name);
参数:
- name: 要获取值的环境变量名称。
返回值:
- 如果环境变量存在,返回一个指向其值的指针。
- 如果环境变量不存在,返回
NULL
。
例子:
#include <stdio.h>
#include <stdlib.h>int main() {char* path = getenv("PATH");if (path != NULL) {printf("PATH is %s\n", path); } else {printf("PATH not set\n");}return 0;
}
获取并打印 PATH
环境变量的值。
使用 getenv()
函数可以在 C 程序中方便地获取系统环境变量,用于程序运行的配置和决策等。它允许程序动态获取运行时环境的信息。
环境变量通常是具有全局属性的
环境变量通常具有全局属性,可以被子进程继承下去
bash_profile
文件
在Linux中,bash_profile
是一个特殊的配置文件,它用于配置 Bash shell 的环境和行为。每当用户登录到系统时,Bash shell 将会执行 bash_profile
文件中的命令和设置。
下面是关于 bash_profile
文件的一些重要信息:
-
作用:
bash_profile
文件用于配置用户的个性化环境,例如设置环境变量、定义别名、执行特定命令等。- 它是用户级别的配置文件,每个用户都可以在自己的主目录中创建一个
bash_profile
文件来定制自己的 Shell 环境。
-
位置:
bash_profile
文件通常位于用户的主目录下,文件名为.bash_profile
。- 用户登录时,Bash shell 会自动查找并执行该文件。如果不存在,则会尝试执行其他类似的文件,比如
.bash_login
或.profile
。
-
内容:
bash_profile
文件可以包含各种 Bash 命令和设置,例如:- 设置环境变量(如
PATH
、PS1
等)。 - 定义别名和函数。
- 运行特定的脚本或程序。
- 进行系统初始化和配置等。
- 设置环境变量(如
-
编辑:
- 用户可以使用文本编辑器(如
vi
、nano
、gedit
等)编辑.bash_profile
文件。 - 修改完成后,需要保存并关闭编辑器,更改将在下次用户登录时生效。
- 用户可以使用文本编辑器(如
-
加载:
- 当用户登录时,Bash shell 会自动执行
.bash_profile
文件中的命令和设置。 - 如果用户需要立即使更改生效,可以使用
source
命令重新加载.bash_profile
,例如:source ~/.bash_profile
。
- 当用户登录时,Bash shell 会自动执行
总之,bash_profile
文件是在 Linux 系统中用于配置用户个性化环境的重要文件之一,它允许用户定义各种环境变量、别名、函数以及其他个性化设置,以满足其特定需求。
先有命令参数表,再有环境变量表
命令参数表通常会先有,然后在命令执行时,该命令会使用当前环境中的环境变量。
nano
、gedit
等)编辑 .bash_profile
文件。
- 修改完成后,需要保存并关闭编辑器,更改将在下次用户登录时生效。
- 加载:
- 当用户登录时,Bash shell 会自动执行
.bash_profile
文件中的命令和设置。 - 如果用户需要立即使更改生效,可以使用
source
命令重新加载.bash_profile
,例如:source ~/.bash_profile
。
- 当用户登录时,Bash shell 会自动执行
总之,bash_profile
文件是在 Linux 系统中用于配置用户个性化环境的重要文件之一,它允许用户定义各种环境变量、别名、函数以及其他个性化设置,以满足其特定需求。
先有命令参数表,再有环境变量表
命令参数表通常会先有,然后在命令执行时,该命令会使用当前环境中的环境变量。