Linux第十一节课 - 进程

发布于:2024-09-19 ⋅ 阅读:(9) ⋅ 点赞:(0)

一个程序从磁盘以文件的形式加载到内存之后,已经变成了进程!

引入管理者和被管理者

1、管理者和被管理者不需要见面!(例如学生和校长!)

2、管理者在不见被管理者的情况下,如何做好管理呢?只要能够得到管理信息,就可以在未来进行管理决策!(管理的本质:通过对数据的管理,达到对人的管理)

3、管理者和被管理者面都不见,怎么才能拿到数据?

通过辅导员(本质上也是执行者 ---> 执行校长的命令)

例如网卡出现问题,这时,驱动程序会将有问题的数据报告给操作系统,此时操作系统检测到硬件网卡出现问题,操作系统自动修复,如果修复不了就向上报给用户说明故障!

如果学生(硬件)太多,此时操作系统会将学生按照结构体的类型整理起来!

类似于链表结构!此时10000个学生就会有10000个结构体对象!

此时,成功的将对学生(硬件)的管理工作,改为对链表的增删改查!

软硬件的数量太大!此时操作系统会根据软硬件的属性进行分类(描述的过程),然后再将分类好的结果按照数据结构的类型进行管理(组织的过程)!

在操作系统中,管理任何对象,最终都可以转化为某种数据的增删查改!(先描述再组织!)

先描述再组织:面向对象编程的核心思想也是!(例如clsaa类)

操作系统改成为硬件的管理对链表的增删查改(这一过程称为---建模)---> 计算机只能这么做!

操作系统中一定存在了大量的数据结构!

如果我们使用printf函数打印东西到显示器上面!(这个过程是从上到下依次贯穿的!)

因此对于C/C++的库函数(lib)和系统调用的关系是上下层的关系!(上下层的调用和被调用的关系!)

总结:

1、计算机管理硬件

  • 描述起来用struct结构体(因为操作系统就是C写的!)
  • 组织起来,用链表或者其他高效的数据结构!

2、系统调用和库函数

  • 在开发角度,操作系统对外会表现为一个整体,但是会暴漏自己的部分接口,供上层开发使用,这部分由操作系统提供的接口,叫做系统调用!
  • 系统调用在使用上,功能比较基础,对用户的要求相对比较高,所有,有心的开发者对部分系统调用进行了适度的封装,从而形成了库!有了库,很利于更上层用户或者进行二次开发!

一、再谈进程 

1、引入

如果进程有成千上百个,操作系统怎么对进程进行规划呢?

也是先描述再组织!!!

一个被加载到内存中的程序,也叫做进程!(进程也叫任务)

也有的教材说:正在运行的程序叫做进程!

正常情况下我们写的myprocess.c和myprocess可执行程序都位于磁盘当中!

此时如果我们运行./myprocess,就会形成一个进程!

开机的本质就是把操作系统从外设搬入到内存当中!!!

就例如我们如果想要运行./myprocess,需要将其加载到内存中,再由CPU进行处理!!!

一个操作系统,不仅仅只能运行一个进程,还可以同时运行多个进程!

操作系统必须对所有的进程管理起来!如何管理呢?--->  先描述,再组织!!!

任何一个进程,再加载到内存的时候,形成真正的进程时,操作系统要先创建描述进程的结构体对象------PCB(process ctrl block)------ 进程控制块

人是怎么辨别一个事物或者对象的?(通过属性认识的!!!)

当属性够多的时候,这一堆属性的集合,就是目标对象!!!

同样的,描述一个进程的时候,如果进程的描述属性足够多,那么我们就可以确定具体的进程!!!(本质就是面向对象!!)

因为操作系统是C语言写的,所有进程本质就是操作系统中的一个结构体类型!!!

PCB是一个结构体,里面存放用于区分不同进程的属性,例如:进程的编号,进程的状态,优先级,相关的指针信息(通过指针找到对应的代码和数据),(struct PCB* next)(可能是以链表的形式进行描述多个进程的)......

PCB也被加载到内存中!而当我们运行一个可执行程序,代码和数据可会被加载到内存当中!此时,我们可以自己给进程一个定义:

内核PCB数据结构对象 + 自己的代码和数据     ---- >进程

但是通常操作系统管理进程不看代码和数据,仅仅是通过PCB对象来管理

当有多个进程的时候,操作系统会根据PCB创建对应的PCB结构体对象!这个结构体对象可以找到自己原来的代码和数据!

此时,在操作系统中对进程的管理变成了对链表的增删查改!!!

因此,此后操作系统对进程管理都是对PCB结构体对象进行管理!!!

上述步骤,任何操作系统都是这样子定义来的

2、那么具体Linux是怎么实现的?

在不同的操作系统,windows/Linux/mac实现的差别有所不同!

课本上称之为PCB,但是在Linux系统中称之为PCB:task_struct;

task_struct是PCB的一种!

  • 在Linux系统中描述进程的结构体叫做task_struct;
  • task_struct是Linux内核的一种数据结构(一种自定义类型),它会被装载到RAM(内存)里并且保存进程的信息!
task_ struct内容分类
  • 标示符: 描述本进程的唯一标示符,用来区别其他进程。(唯一的一个编号!)
  • 状态: 任务状态,退出代码,退出信号等。
  • 优先级: 相对于其他进程的优先级。
  • 程序计数器: 程序中即将被执行的下一条指令的地址。(进程在运行的时候会经常被其他事物影响而停止或者中断,此时记录下运行到当前位置的地址,方便后面接着运行!)
  • 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针(方便找到对应的数据)
  • 上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
  • I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
  • 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
  • 其他信息

小总结:

  • pcb -> task_struct 结构体里面包含了进程的所有属性;
  • Linux中如何组织进程  ---> Linux系统中,最基本的组织进程采用task_struct的方式,采用的是双链表组织的(一个PCB对象可能不止在链表中,还有可能在二叉树等其他数据结构中!)

例如使用PCB_*next链入链表;使用PCB_*queue链入队列;

对进程的管理工作,取决于将进程放进那个被管理的数据结构类型中!

3、查看进程的相关属性

ps命令可以查看属性;

运行两个一模一样的程序会生成两个进程!

  • PID就是其中进程唯一的ID值,用于区分不同的进程;

Linux系统中存在一个目录

ls /proc

可以通过 /proc查看当前系统下的所有进程;

下面的grep -- color=autor 实际上就是grep对应的进程!

grep的关键字里也有process,因此当它在执行过滤系统当中的进程时,首先会把自己变成进程,然后自己才会被CPU调度,执行自己的过滤代码!

通过ls查看会发现根据ID号码排列的一个个目录, 系统当中启动的所有进程,默认会在 /proc下面创建一个以该进程PID命名的文件夹!该目录下保存了进程的大部分属性!

ls /proc/20639

可以改看该PID下进程的相关信息

如果此时再将程序关闭,会发现文件夹消失!

再次运行后进程的PID号码发生改变!(大概率会发生改变)

proc目录中包含的是系统动态目录下的相关进程的信息!

cwd  --- > current work dir 指的是当前进程的工作目录

在C语言中,如果使用fopen创建一个文件,这个文件一般在当前目录下存放!

且为什么在一个目录下touch test.c是在当前目录下创建的?

实际上,当touch这个指令运行起来变为进程,默认进程在哪个目录,这个进程所在的目录就是当前目录!(PCB属性会记录当前所在的Linux的绝对路径为但当前路径!)

实际上fopen在运行的时候会将"log.txt"拼接到cwd的后面!


网站公告

今日签到

点亮在社区的每一天
去签到