进程间切换
- 1. 前言
- 2. 进程间切换
- 3. Linux2.6内核进程调度队列
- 4. main函数参数--命令行参数
- 5. 利用main函数参数实现简易计算器
- 6. 模拟实现Linux中的bash指令
- 7. 环境变量PATH初认识
- 8. 修改环境变量PATH
- 9. 总结
1. 前言
掌握了前面文章中
Linux进程相关的内容后,
本篇文章将进行一些实践
包括自制计算器,自己写bash指令等
本章重点:
2. 进程间切换
我们知道一个事实,CPU在调度进程时
并不是一个进程一直在占用CPU资源
它过段时间会被取下来放入其他进程
所以这中间肯定存在进程切换这一过程
两个问题:
没运行完的进程数据后来去哪儿了?
当一个进程被取下时
它在CPU的数据是否会被删除?
第一个问题
所以其实在进程运行时,是会使用到
这些寄存器的!进程产生的各种数据
会在寄存器中进行临时保存!
进程在切换时会不断对自己的数据
进行保存(被取下时)和恢复(重新运行时)
当进程进行保存时是保存寄存器中的数据
而不是寄存器本身,并且这些数据会被保存
至一个进程的PCB当中!
第二个问题:
3. Linux2.6内核进程调度队列
注意,这部分是选学,有余力的同学可以看看
请看下图(着重看红框和篮框)
我们着重讲解活跃进程和过期进程的交互!
3.1 活跃进程
首先知道一个事实,Linux中的进程
优先级范围是60~99总共40个等级
其次,运行队列中分活跃进程组和
过期进程组,这个后面再说它们的功能
先来看活跃进程的queue:
3.2 过期进程
现在有一个问题:当一个优先级为90的
进程正在运行,但是此时突然多了一个优
先级为80的进程,那么这个多加入的进程也
是放入活跃队列中和其中的进程抢占资源吗?
它的原理请看下图:
那么当活跃队列中的进程被调度完了
此时CPU是去过期进程调度吗?
答案是不!系统直接使用swap()函数
将活跃进程和过期进程的内容交换
CPU还是在处理活跃队列的进程!
4. main函数参数–命令行参数
main函数其实是有参数的,本篇文章
我只介绍main函数的两个参数
int main(int argc , char* argv[]);
这两个参数又被称为命令行参数
argv是一个数组,指向的元素类型是char*
也就是说argv是一个字符串数组
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;
}
通过下面的视频观察现象:
main
可以发现一个问题:
看下图得出结论:
注:将命令行输入的字符串放入argv数组是OS干的!
5. 利用main函数参数实现简易计算器
既然main函数参数可以读到命令行
中输入的字符串,所以可以用代码实现
一个简易的计算器,代码如下:
#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] d1 d2\n",argv[0]);
return 1;
}
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("输入操作符错误");
return 0;
}
使用方法:
- 用户必须先输入可执行程序:a.out
- 第二个字符串输入加减乘除其中一个
- 第三,第四个字符串输入操作数
- 若其中有一个环节输入错误会报提醒
6. 模拟实现Linux中的bash指令
当模拟实现了计算器后,我们隐约可以
发现,其实Linux下的指令如ls,pwd或touch
其实就是调用了不同的可执行程序来完成的!
mytouch代码如下:
#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下输入指令创建文件:
如果有需要,我们可以自己写一份
可执行程序来模拟Linux下所有的指令!
7. 环境变量PATH初认识
上面所说的内容你可能能理解
就是利用了main函数的参数进行各种运用
但是有几个问题需要解决:
为什么我们自己写的程序运行时要加./
但是系统中的指令:ls,pwd等不用加./?
我们自己写的指令能不能不加./?
这不得不引出一个概念: 环境变量
保存程序的默认搜索路径的环境变量
叫做: PATH
在运行程序时,系统会去PATH中
找当前可执行程序在不在这些路径中
如果在就直接执行程序,不在就报错
查看环境变量PATH:
这些路径以冒号:为分割
因为我们自己写的程序不在这些路径中
所以我们需要加上./来运行程序!
8. 修改环境变量PATH
要想我们的指令像系统指令一样运行
我们可以将自己写的程序的路径加入
到环境变量PATH中!
此时我已经将我的路径添加到PATH了
现在我直接像系统指令一样运行我的指令:
9. 总结
进程的学习需要理论和实践相结合
本篇文章主要是实践部分,而然有两个
问题剖给大家:main函数就只有两个参数吗?
环境变量到底有什么用处?