并行和并发
- 并行
多个进程在多个 CPU 下分别,同时进行运行。
- 并发
多个进程在一个 CPU 采用进程切换的方式,在一段时间内,让多个进程都得以推进,称之为并发。
-
CPU 中的寄存器扮演什么角色?
-
寄存器:cpu 内的寄存器里面保存的是进程相关的数据。CPU 寄存器里面保存的是进程的临时数据–统称为:进程的上下文。临时数据数据量不大,所以被放在进程里的 PCB 中。
-
进程在从 CPU 上离开的时候,要将自己的上下文数据保存好,甚至带走。保存的目的是未来能够恢复。
-
进程在被切换的时候有以下步骤:
- 保存上下文
- 恢复上下文
-
提高效率,将高频进程数据放入寄存器中。
-
环境变量
基本概念
PATH
- 例子
在 linux 中输入以下指令
echo $PATH
linux 会输出一些以冒号为分割的路径,当在 linux 下执行指令时(ls,pwd 等),操作系统会在这些路径下搜索。
-
PATH 定义
linux 的指令搜索路径
-
如果将自己编写的程序添加到环境变量中会怎么样?
无需使用./即可运行,就像系统指令一样,直接输入程序名即可运行,无需添加./。
-
如何将自己编写的程序添加到环境变量?
- PATH=$PATH:程序路径 (直接在后面添加)
- PATH=程序路径 (这样写的话,就会使得 PATH 环境变量中只含有刚刚添加的路径,覆盖原先的路径了,会导致无法使用系统指令)
- 若将环境变量改错了,只需重新启动 XShell 即可。
-
常见问题
- 为什么我们执行系统指令时不用添加./?
因为指令也是可执行程序,操作系统会维护一个 PATH 变量,这是一个指令搜索路径。
- which 搜索指令从哪里搜索?
在 PATH 环境变量中搜索。
- 为什么我们执行系统指令时不用添加./?
查看所有环境变量
-
指令:
env
-
C 指令
getenv("PATH")
HOME
echo $HOME
什么是环境变量
环境变量是系统提供的一组 name=value 形式的变量。不同的环境变量有不同的作用,通常具有全局属性。
命令行参数
在文件 mycmd中:
//char* argv[] 是指针数组,有多少个元素由argc决定
int main(int argc, char* argv[])
{
for (int i = 0; i < argc; i++)
{
printf("argv[%d]->%s", argc, argv[i]);
}
}
-
./mycmd
输出:argv[0]->./mycmd
-
./mycmd -a
输出:argv[0]->./mycmd argv[0]->-a
-
./mycmd -a -b
输出:argv[0]->./mycmd argv[0]->-a argv[0]->-b
- 命令行参数
- 在命令行中输入的 ./mycmd -a -b ,其实输入的是 “./mycmd -a -b” ,bash 作命令行解释时就会把这个字符串打散成 3 个字符串(“./mycmd”,“-a”,“-b”),以空格为分隔。
- 打散之后,有几个字符串就初始化 argc 为几。把每一个字符串的起始地址保存到 argv 中。然后才把 argc 和 argv 传递给 main 函数。这叫做命令行参数。
- 为什么要这样做?
int main(int argc, char* argv[])
{
if (argc != 2)
{
printf("./mycmd -[a|b|c|..]");
return 0;
}
if (strcmp(argv[1], "a") == 0)
{
printf("功能1\n");
}
else if (strcmp(argv[1], "b") == 0)
{
printf("功能2\n");
}
else if (strcmp(argv[1], "c") == 0)
{
printf("功能3\n");
}
else
{
printf("default\n");
}
}
-
./mycmd -a
输出功能1
-
./mycmd -b
输出功能2
- 结论
- 为什么以前的指令能带不同的选项呢?所有的指令对应的选项,本质上是同一个指令,但是根据不同的选项,可以有不同的功能。
- 为指令或工具等提供命令行选项的支持。
常见问题
-
main 函数中只有 int argc 和 char *argv[]吗?还可以再添加参数吗?
- 可以!!!,还可以添加 char *env[] 是一个环境变量列表。
- char *env[]和 char *argv[]结构一模一样,都是指针数组,里面放指针,最后一个默认为 NULL。
-
C/C++代码一共两张核心向量表
- 命令行参数表 char *argv[]
- 环境变量表 char *env[]
-
输出环境变量表
int main(int argc, char *argv[],char *env[]) { for (int i = 0; env[i]; i++) { printf("env[%d]->%s\n", i, env[i]); } }
-
我们所运行的进程都是子进程,bash 本身在启动的时候会从操作系统的配置文件中读取环境变量,我们对应的子进程会继承父进程交给我的环境变量。
-
创建自己的环境变量
export My_Value=12345678
-
取消自己创建的环境变量
unset My_Value
-
本地变量和内建命令
本地变量
本地变量不会继承,只在本 bash 内有效
-
例如:
a=1 echo $a//(输出 1)
-
将本地变量转化为环境变量
export a
命令的分类
常规命令
通过创建子进程完成的
内建命令
bash 不创建子进程,而是自己亲自执行。类似于 bash 调用了自己写的或者系统提供的函数。