• 进程的一些概念以及环境变量


    本篇笔记记录自己理解Linux进程的一些概念作为复习,中间或许与标准存在些许误差,若有不对或者不准确的地方,还望各位铁子评论更正,一起进步呀。


    目录

    竞争性

    独立性

    并行

    并发

    并发分析

    时间片

    进程的切换

    竞争分析 

    抢占式内核

    Linux下确保优先级的方式

    环境变量

    指定环境变量

    所有环境变量

    常见的环境变量

    通过main函数传参理解命令行及选项

    获取环境变量的方式

    1. main函数传参直接打印

    2. 通过environ获取

    3. 系统调用获取环境变量


     

    竞争性

    系统进程数目众多,而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

    常见的环境变量

    1. HOSTNAME //主机名
    2. SHELL //shell脚本类型
    3. HISTSIZE //能保存的历史命令数的多少
    4. SSH_CLIENT //IP地址
    5. USER //使用者
    6. PWD //当前路径
    7. LANG //支持的编码格式
    8. HOME //不同用户对应的家目录

    通过main函数传参理解命令行及选项

    main函数是可以传递参数的,通过给main函数传递参数,可以实现我们Linux下命令行和选项的操作:

    1. #include
    2. int main(int argc, char *argv[])
    3. {
    4. int i=0;
    5. for(i=0;i
    6. {
    7. printf("argv[%d]:%s\n",i,argv[i]);
    8. }
    9. return 0;
    10. }

    argc 代表着输入的参数个数,argv指针数组存储着输入的参数,运行如下:

    那么我们可以由这来写一个简单的命令行计算器:

    获取环境变量的方式

    1. main函数传参直接打印

    main函数除了可以传上述两个参数,还有第三个参数--环境变量:

    1. //获取环境变量方式1
    2. #include
    3. int main(int argc, char *argv[], char *env[])
    4. {
    5. int i=0;
    6. for(i=0;env[i];i++)
    7. {
    8. printf("env[%d]: %s\n",i,env[i]);
    9. }
    10. return 0;
    11. }

    默认第三个参数指向的是环境变量,直接打印即可:

    2. 通过environ获取

    用C语言提供的第三方变量environ来获取环境变量,不需要我们自己定义,只需要提前声明即可:

    1. //获取环境变量方式2--C语言提供的第三方变量
    2. #include
    3. int main()
    4. {
    5. extern char** environ;
    6. int i=0;
    7. for(i=0;environ[i];i++)
    8. {
    9. printf("%d: %s\n",i,environ[i]);
    10. }
    11. return 0;
    12. }

    用extern声明,注意类型,也是相当于一个指针数组,for循环的判断条件与第一种获取方式的用法一样,不为空继续循环,为空终止循环

    3. 系统调用获取环境变量

    最简单常用的方式就是系统调用, 获取指定的环境变量:

    1. //获取环境变量的第三种方式--系统调用
    2. #include
    3. #include
    4. int main()
    5. {
    6. char *val = getenv("PATH");
    7. printf("%s\n",val);
    8. return 0;
    9. }

    小知识:环境变量是具有全局性的,是可以被子进程继承下去的

  • 相关阅读:
    软件测试技术之可用性测试之WhatsApp Web
    环境搭建---部署rabbitmq集群
    Maven 笔记
    MySQL语句
    LeetCode 35.搜索插入位置
    [设计模式] 装饰器模式
    高通WLAN框架学习(31)-- Power save
    【数据结构】:队列的实现
    JAVA编程规范之应用分层
    ROS系统使用usb_cam摄像头
  • 原文地址:https://blog.csdn.net/weixin_53316121/article/details/126325221