本篇笔记记录自己理解Linux进程的一些概念作为复习,中间或许与标准存在些许误差,若有不对或者不准确的地方,还望各位铁子评论更正,一起进步呀。
目录
竞争性
系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的,为了高效完成任务,更合理竞争相关资源,便具有了优先级。
独立性多进程运行,需要独享各种资源,多进程运行期间互不干扰。
并行不同进程在不同CPU下分别同时运行,称为并行
并发进程在CPU下并不是一次就运行完成的;多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发。
并发分析
从概念上来看,很好理解,就是切换调用,让大家牵手一起走的过程
时间片
那么每个进程要走多久呢,是由CPU决定的;
时间片即CPU分配给各个程序的时间,每个线程被分配一个时间段,称作它的时间片;
当一个进程的运行时间到达后,会自动切换到下一个进程,下一个进程继续占用CPU资源来完成自己的调度任务;
进程的切换
那么进程是如何切换的?
一个进程在CPU上运行,是要产生计算的临时数据的,我们把进程在CPU上产生的临时数据叫做上下文数据;
上下文数据都是很重要的,因为它代表着进程调用的进度,因此它是不能丢失的,上下文数据的存在可以当进程再次调用时,接着上下文数据的进度继续运行进程;
若没有保存上下文进度,那么再次调用原进程,在固定的时间片内,是运行不完的,如此重复,只会陷入原地踏步的死循环;
因此在切换至下一个进程时,必须保存上下文数据。
上下文数据不能保存在CPU的寄存器上,因为CPU的寄存器还要运算存储下一个调度的进程的数据;一个进程的上下文数据保存在自己的 task_struct 中。
竞争分析
因为有了竞争,因此有了优先级存在,根据优先级,进程们去访问资源,有了有序性,提高了效率;那么在多进程状态下,操作系统如根据进程的优先级确保有序性?
Linux下进程是由进程控制块 task_struct 和 文件 组成,但是调用进程是通过 task_struct 来管理的,在CPU中存在运行队列,连接着各个进程的 task_struct ,根据队列顺序依次调用进程;
抢占式内核
如果插入一个优先级很高的进程,调度器将会把低优先级且正在调度的进程从CPU上剥离,放上优先级高的进程运行,这就是进程抢占;
在不发生进程抢占时,插入一个优先级不高不低的进程,根据队列先进先出的规则,是必然不可能将此进程直接插入运行队列的中间的,因此一个队列是确定不了进程的优先级的!!
Linux下确保优先级的方式
环境变量
我们自己写出来的可执行程序与Linux下的指令本质上并无区别,起始都是可执行程序,为何我们执行自己的程序需要带路径?而使用命令就直接可以运行呢?
因为命令都已经被设置成了环境变量,我们的可执行程序设置为环境变量,也是可以直接运行的。
如何将我们的可执行程序做到向指令一样?
1. 将可执行程序放入到保存系统指令的目录下就可以了
2. 通过export将环境变量PATH改变
环境变量PATH是查找所有环境变量时的路径,:是路径分隔符,将可执行程序的路径放在查找环境变量的路径下就可以了
如何打印环境变量的详细内容?
指定环境变量
echo $环境变量名
所有环境变量
env
常见的环境变量
HOSTNAME //主机名 SHELL //shell脚本类型 HISTSIZE //能保存的历史命令数的多少 SSH_CLIENT //IP地址 USER //使用者 PWD //当前路径 LANG //支持的编码格式 HOME //不同用户对应的家目录
通过main函数传参理解命令行及选项
main函数是可以传递参数的,通过给main函数传递参数,可以实现我们Linux下命令行和选项的操作:
#include<stdio.h>
int main(int argc, char *argv[])
{
int i=0;
for(i=0;i<argc;i++)
{
printf("argv[%d]:%s\n",i,argv[i]);
}
return 0;
}
argc 代表着输入的参数个数,argv指针数组存储着输入的参数,运行如下:
那么我们可以由这来写一个简单的命令行计算器:
获取环境变量的方式
1. main函数传参直接打印
main函数除了可以传上述两个参数,还有第三个参数--环境变量:
//获取环境变量方式1
#include <stdio.h>
int main(int argc, char *argv[], char *env[])
{
int i=0;
for(i=0;env[i];i++)
{
printf("env[%d]: %s\n",i,env[i]);
}
return 0;
}
默认第三个参数指向的是环境变量,直接打印即可:
2. 通过environ获取
用C语言提供的第三方变量environ来获取环境变量,不需要我们自己定义,只需要提前声明即可:
//获取环境变量方式2--C语言提供的第三方变量
#include <stdio.h>
int main()
{
extern char** environ;
int i=0;
for(i=0;environ[i];i++)
{
printf("%d: %s\n",i,environ[i]);
}
return 0;
}
用extern声明,注意类型,也是相当于一个指针数组,for循环的判断条件与第一种获取方式的用法一样,不为空继续循环,为空终止循环
3. 系统调用获取环境变量
最简单常用的方式就是系统调用, 获取指定的环境变量:
//获取环境变量的第三种方式--系统调用
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *val = getenv("PATH");
printf("%s\n",val);
return 0;
}
小知识:环境变量是具有全局性的,是可以被子进程继承下去的