【Linux进程】 进程的理解

目录

前言

1. 系统管理

2. 进程

2.1 概念

2.2 进程的调度

2.3 描述进程-PBC

3. 查看进程

 4. 通过系统调用获取进程标示符


前言

      在计算机科学领域,进程是一种重要的概念,在日常学习中也经常遇到进程这个概念,那么进程到底是什么?我们又应该如何去理解,本文将为你详细解释什么是进程,以及如何在Linux环境下如何查看进程。

在这里插入图片描述

1. 系统管理

为什么要有系统管理?

  • 对下管理好硬件资源

操作系统通过对硬件资源的管理,确保了系统的稳定、高效和安全的运行环境

  • 对上提供良好的运行环境

操作系统对外会表现为一个整体,但是会暴露自己的部分接口,供上层开发使用——系统调用接口

【Linux进程】 进程的理解_第1张图片

系统调用

系统调用接口:由操作系统提供,也叫系统调用函数,这些函数是用C语言编写的函数(Linux环境)

        大多数操作系统中,用户通常不允许直接访问底层硬件。用户要想调用底层硬件必须经过操作系统。

库函数

        用户在使用时,可以直接调用系统调用接口,但系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者对部分系统调用进行了适度封装,从而形成库,有了库,就很有利于更上层用户或者开发者进行二次开发。

小结

系统调用和库函数的关系:

系统调用由系统提供,库函数由用户层提供,它们是上下层的关系

2. 进程

了解完整个计算机体系结构之后,再来探讨什么是进程

2.1 概念

什么是进程?

在教材当中的定义:加载到内存的程序、正在运行的程序等。进程究竟是什么,我们要如何去理解进程?

        我们在使用电脑时,电脑可以同时启动多个程序(将多个.exe文件加载到内存),程序在运行之前,必须要把程序先加载到内存,系统要对加载到内存的(可执行)程序进行管理,如何管理? ——先描述,再组织

先描述,再组织

        定义一个struct结构体,结构体包含进程几乎所有的属性字段,如:状态、优先级、标识符、内存指针字段、struct xxx *next...

这些结构以链表的形式进行连接,通过对链表的增删查改就可以对进程进行管理。

【Linux进程】 进程的理解_第2张图片

        可执行程序从磁盘加载到内存当中,没有识别标识的话,计算机就无法识别每个可执行程序,为了方便管理,于是便将每个可执行程序描述起来形成一个结构体,这个结构体也叫做进程控制块(process control block)简称PCB

        计算机将每个可执行程序的PCB以链表的形式连接起来,于是就将进程的管理,转变成了对PCB增删查改。

所以什么是进程?

内核PCB对象(内核数据结构) + 可执行程序 = 进程

2.2 进程的调度

进程通过链表连接,这些进程又是怎么被调度运行的?

【Linux进程】 进程的理解_第3张图片

        在CPU内部可以有一个运执行队列的数据结构,通过这个队列结构来实现对进程的调度。运行时进程可以被动态的调度,其实就是将可执行程序的PCB放入到执行队列当中。

也就是说:所有对进程的控制以及操作,只和进程的PCB有关,和进程的可执行程序无关。

        PCB可以被放在任何数据结构当中,日常中的数据结构增删查改及练习,其实也就是对进程的管理方法。

2.3 描述进程-PBC

task_struct-PCB的一种

        在Linux中描述进程的结构体叫做task_structtask_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息

task_ struct内容分类

  • 标示符: 描述本进程的唯一标示符,用来区别其他进程。

  • 状态: 任务状态,退出代码,退出信号等。

  • 优先级: 相对于其他进程的优先级。

  • 程序计数器: 程序中即将被执行的下一条指令的地址。

  • 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针

  • 上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。

  • I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。

  • 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。

  • 其他信息

         这些task_ struct中的数据全部都属于操作系统内部的数据。要获取这些数据(如pid),必须要调用系统调用。

【Linux进程】 进程的理解_第4张图片

3. 查看进程

了解完进程,我们在Linux环境下查看一下进程:

ps ajx

【Linux进程】 进程的理解_第5张图片

验证一下上边的结论:

我们可以在Linux环境下执行以下代码:

#include  
#include  
int main()
{ 
    while(1)
    { 
        printf("Hello world!\n");
        sleep(1); 
    } 
return 0;
 }

将代码编译执行:

此时程序就变成了进程,我们可以使用grep筛选查看:

ps ajx | head -1 && ps ajx | grep myprocess

【Linux进程】 进程的理解_第6张图片

为什么有两个?

我们在筛查时,使用了grep指令,它也是一个程序,在执行搜索myprocess时它也是一个进程,所以第二个是grep的进程。

所以,只要程序一旦被运行运行就会产生进程

使用while循环每隔1秒筛查一次myprocess进程,注意观察筛查变化:

 指令:

 while :; do ps ajx | head -1 && ps ajx | grep myprocess | grep -v grep; sleep 1; done

 可以根据生成的可执行程序名称进行适当修改。

【Linux进程】 进程的理解_第7张图片

 可以清晰的看到一个进程的产生与结束。

 4. 通过系统调用获取进程标示符

  • 进程id(PID)
  • 父进程id(PPID)

 在Linux中,一般普通进程都要它的父进程

 在Linux环境下执行下面这个程序:

#include 
#include 
#include
 int main()
   {
         pid_t id = getpid();
         pid_t fid = getppid();
         while(1)
         {
             printf("Hello world! pid: %d ppid: %d\n",id,fid);                                                  
             sleep(1);
         }
  
         return 0;
  
  }

 我们还是使用老方法,使用while循环每隔1秒筛查一次myprocess进程,注意观察筛查变化:

通过观察可以发现,每次启动时进程的id(pid)都不一样,这是因为:

每次启动的进程,都是一个新的进程

 虽然pid每次都会变,但是父进程(ppid)没有变化,那这个父进程(ppid)到底是什么?

 筛查指令:

ps ajx | head -1 && ps ajx | grep 4599

我的ppid是4599,可根据自己的ppid进行修改。

【Linux进程】 进程的理解_第8张图片

 筛查结果是bash,bash是我们的命令行解释器

 所以所有在命令行启动的进程,都是bash的子进程


 总结

         通过深入了解进程的概念和原理,我们可以更好地理解计算机系统的运行方式,以上就是本文全部内容,希望对你有所帮助,感谢阅读!

你可能感兴趣的:(linux,运维,服务器)