进程间切换
我们在之前讲过CPU在调度进程时,不是一个进程一直占用CPU,而是会过段时间就会放入其他进程,那么就一定存在进程切换的过程
运行到一半的进程数据去哪了
第一个想到的问题就是,当一个进程中途被取下,再次放上去时,计算机怎么知道这个进程运行到哪里了
了解计算机组成原理的朋友都知道CPU中有一些寄存器,例如eax、ebx、esp、ebp、eip等
- eax可以帮助函数返回一个值
- esp和ebp用来维护函数的栈帧
- eip则会保存当前代码运行到了哪一行
所以在进程运行时,这些寄存器就会临时保存进程产生的各种数据
这里需要注意的是,进程在切换时会不断的对自己的数据进行保存和恢复,当进程进行保存时是保存寄存器中的数据,而非寄存器本身,这些数据会被保存到进程的PCB中
进程被取下时,CPU数据是否会被删除
事实上,一个进程被取下时,CPU不会删除他的临时数据,而是当下一个进程被放入时,直接进行覆盖
命令行参数
我们之前在学习C/C++的时候,有的默认代码在main函数内也放置了两个参数
int main(int argc, char* argv[]);
这两个参数也称之为命令行参数,argv是一个数组,指向的元素是char*,也就是一个字符串数组,而argc表示数组元素的个数
现在我们并不知道这个数组中存放的是什么字符串,但是我们可以写个代码验证一下,既然知道数组名和元素个数,不如直接打印出来看看
#include<stdio.h>
int main(int argc, char* argv[])
{
int i=0;
for(i=0; i<argc; i++)
{
printf("%d:%s\n", i, argv[i]);
}
return 0;
}
我们发现当直接运行可执行程序的时候,他直接打印了0:./a.out
,而我们在后面以空格分隔输入任意字符串时,argv数组里面存的就是我们输入的字符串
原来命令行参数和我们运行的Linux命令的参数其实是同一个意思,再结合我们之前学习,所谓的Linux命令只是封装好的C语言程序,那么命令的大概执行逻辑我们也能猜得到了
需要注意的是,将命令行输入的字符串放入argv数组其实是操作系统干的事情
波兰表达式计算器
在了解完命令行参数之后,我们其实就可以使用这个性质来写一个简单的波兰表达式的运算解释器,类似于我们之前使用C语言模拟实现的Lisp解释器
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(int argc, char* argv[])
{
if(argc != 4)
{
printf("输入格式应为:%s OP[add|sub|mul|div] num1 num2", argv[0]);
}
int x = atoi(argv[2]);
int y = atoi(argv[3]);
if(strcmp(argv[1], "add")==0)
printf("%d + %d = %d\n",x,y,x+y);
else if(strcmp(argv[1], "sub")==0)
printf("%d - %d = %d\n",x,y,x-y);
else if(strcmp(argv[1], "mul")==0)
printf("%d * %d = %d\n",x,y,x*y);
else if(strcmp(argv[1], "div")==0)
printf("%d / %d = %d\n",x,y,x/y);
else
printf("操作符错误\n");
return 0;
}
模拟实现bash指令
我们刚刚说了Linux的bash指令其实就是调用了不同的可执行程序来完成的
例如touch指令,本质上就是在C语言程序中创建一个和输入名称一样的文件,来达到间接创建文件的目的
这样就省去了每次都要写不同的C语言程序再编译运行的过程
我们可以模拟实现
#include<stdio.h>
int main(int argc, char* argv[])
{
if(argc != 2)
{
printf("touch missing file operand\n");
return 1;
}
FILE* fp = fopen(argv[1],"w");
if(fp!=NULL)
fclose(fp);
return 0;
}
这样我们就可以自己来写可执行程序,来执行Linux下的命令
环境变量PATH
但是聪明的朋友已经注意到了,我们在执行命令的时候需要加上./
但是执行Linux自带的命令却不需要
首先我们需要知道为什么要加上./
,这两个符号的目的其实就是为了告诉操作系统你要执行的程序的路径是什么
经常给电脑配置开发环境的同学可能经常使用这个概念,例如Qt环境,JAVA环境等,我们需要复制软件的安装目录粘贴到PATH中
这个东西就叫做环境变量,其实就是保存程序的默认搜索路径,当我们运行程序的时候,这个命令名称如果在环境变量中找不到,就会报错
查看环境变量的命令是echo $PATH
因为我们自己写的程序步骤这些路径中,所以需要加上./
修改环境变量
我们也可以将自己写的程序路径加入到环境变量,使用PATH=$PATH:路径
即可
例如
需要注意的是当路径添加后,重启系统之时,你添加的环境变量就会自动消失,需要重新添加,如果想一劳永逸,不如直接把可执行程序放在默认的路径中