Linux-冯诺依曼体系结构,操作系统,进程,PCB,进程状态,僵尸进程,孤儿进程

目录:

  • 1.冯诺依曼体系结构
  • 2.操作系统
    • 2.1 基本概念
    • 2.2 设计OS的目的
  • 3.进程
    • 3.1 基本概念
    • 3.2 查看进程信息
  • 4. 描述进程-PCB
    • 4.1 基本概念
    • 4.2 并发和并行
    • 4.3 struct内容分类
    • 4.3 进程状态
    • 4.4 进程创建
      • 4.4.1 getpid()函数
      • 4.4.2 getppid()函数
      • 4.4.3 fork()函数
  • 5. 僵尸进程&僵尸状态
  • 6. 孤儿进程
    • 6.1 问题1:
    • 6.2 问题2:

1.冯诺依曼体系结构

生活中我们常见的计算机(eg:笔记本),不常见的计算机(eg:服务器),大部分都遵守冯诺依曼体系
Linux-冯诺依曼体系结构,操作系统,进程,PCB,进程状态,僵尸进程,孤儿进程_第1张图片
特点

•    数据存储在"内存"当中
•    计算机当中的数据一切皆二进制

对冯诺依曼体系结构中各部分之间关系的理解

Linux-冯诺依曼体系结构,操作系统,进程,PCB,进程状态,僵尸进程,孤儿进程_第2张图片
CPU ,寄存器,存储器之间的关系犹如古代皇上,太监,大臣之间的关系
   •    CPU的功能相当于皇上,寄存器的功能相当于太监,存储器的功能相当于大臣,大臣将(存储器)反馈上来的奏折(数据)交由太监(寄存器),再由太监(寄存器)将奏折(数据)传递给皇上(CPU)进行批阅(处理),等皇上(CPU)批阅完奏折(处理完数据),再将奏折(数据)交于(传递)太监(寄存器)反馈(返回)给大臣(存储器)

2.操作系统

2.1 基本概念

任何计算机系统都包含一个基本的程序集合,称为操作系统(OS),笼统的理解,操作系统包括:

•    内核(进程管理,内存管理,文件管理,驱动管理)
•    其他程序(eg:函数库,shell程序)
 
      操作系统 = 操作系统内核 + 一堆应用

2.2 设计OS的目的

操作系统是软件,操作系统在管理计算机的软硬件资源
设计目的

•    与硬件交互,管理所有的软硬件资源
•    为用户程序(应用程序)提供一个良好的执行环境

那么OS是如何进行管理的呢?

     管理 = 描述 + 组织
 
•    描述:自定义数据类型 eg:struct结构体
•    组织:使用链表或其他高效的数据结构

系统调用接口(函数)和库函数的区别

•    系统调用接口(函数):操作系统为程序员提供的函数,程序员调用这些函数更好的使用操作系统管理的资源
•    库函数:程序员对部分系统调用函数进行适度的封装,从而形成了库
eg:strcpy strlen malloc free

3.进程

3.1 基本概念

什么是程序?

程序就是经过源代码编译出来的文件,且程序是静态的

什么是进程?

进程是程序运行是的示例,是动态的(进程是程序运行状态时产生的一个实例);从内核的角度来看,进程是操作系统分配资源的实体

3.2 查看进程信息

ps aux 查看当前操作系统的进程信息
Linux-冯诺依曼体系结构,操作系统,进程,PCB,进程状态,僵尸进程,孤儿进程_第3张图片
让如下代码跑起来
Linux-冯诺依曼体系结构,操作系统,进程,PCB,进程状态,僵尸进程,孤儿进程_第4张图片
Linux-冯诺依曼体系结构,操作系统,进程,PCB,进程状态,僵尸进程,孤儿进程_第5张图片
通过管道符过滤查找当前运行的程序产生的进程信息
ps aux | grep ./main
在这里插入图片描述
此时会查看到两个./main的进程信息

为什么会产生两个./main的进程信息
• 第一行是正在运行程序产生的进程信息
• 第二行是因为在执行ps aux | grep ./main命令时,
在命令结束之前,将grep产生的进程信息也保存下来最终返回

4. 描述进程-PCB

4.1 基本概念

进程信息被放在一个叫进程控制块(PCB)的数据结构中,可以理解为进程属性的集合;Linux操作系统下的PCB是task_struct,相当于结构体

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

4.2 并发和并行

并行:多个进程在同一时刻拥有不同的CPU进行运算,称之为并行
eg:八车道,同一时刻每个车道都可以有一个车通行
并发:多个进程在同一时刻只能由一个进程拥有CPU进行运算,称之为并发
eg:单车道同一时刻只能有一个车通过

4.3 struct内容分类

• 进程标识符(PID):在操作系统中唯一标识一个进程,用来区别其他的进程

• 进程状态:用来表示进程的任务状态,退出代码,推出信号等

程序计数器:保存进程即将运行的下一条指令的地址

上下文数据:保存了寄存器中的内容

• 内存指针:指向了程序地址空间(指向堆区,数据段,代码段等)

• I/O状态信息:保存了当前进程打开文件的信息
==> /proc:保存了当前操作系统维护的所有进程信息,每一个进程都是一个文件夹
Linux-冯诺依曼体系结构,操作系统,进程,PCB,进程状态,僵尸进程,孤儿进程_第6张图片
查看当前进程的进程号在这里插入图片描述
cd到该文件夹下在这里插入图片描述
cd到该文件夹下的fd文件夹查看它对应的I/O流
Linux-冯诺依曼体系结构,操作系统,进程,PCB,进程状态,僵尸进程,孤儿进程_第7张图片

• 记账信息:使用cpu的时长,占用内存的大小

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

4.3 进程状态

从大的方面说,进程有三个状态:就绪状态,运行状态,阻塞状态

细分角度来水,进程共有7种状态:

•    R状态:运行状态–>包含就绪和运行两种状态(等待和运行两种状态)
 
•    S状态:可中断睡眠状态–>进程在等待事件完成
 
•    D状态:不可中断睡眠状态
 
•    T状态:暂停状态
–>ctrl+z使一个进程变成暂停状态,暂停后进程仍然存在
–>ctrl+c暂停后进程不存在
 
•    t状态:跟踪状态–>在gdb调试时会出现
 
•    X状态:死亡状态
 
•    Z状态:僵尸状态(后面和僵尸进程一起讲)

fg可以使Ctrl+z暂停的程序回复运行

4.4 进程创建

4.4.1 getpid()函数

getpid()函数:用来获取当前进程的pid号,谁调用获取谁的

4.4.2 getppid()函数

getppid()函数:获取当前进程的父进程的pid号,谁调用获取谁的父进程

测试如下

代码如下Linux-冯诺依曼体系结构,操作系统,进程,PCB,进程状态,僵尸进程,孤儿进程_第8张图片
查看当前可执行程序的进程信息和输出结果对比Linux-冯诺依曼体系结构,操作系统,进程,PCB,进程状态,僵尸进程,孤儿进程_第9张图片

4.4.3 fork()函数

fork()函数:可以让程序员在代码中创建一个子进程
 
pid_t fork(void)
 
   •    没有参数
 
   •    pid_t:本质是整形
 
   •    返回值:若创建子进程失败,返回-1;若创建子进程成功,对父进程,返回 >0 的数(其实就是返回子进程的PID号);对于子进程,返回 ==0 的数
 
   •    原理:fork创建子进程的PCB是拷贝父进程的PCB
Linux-冯诺依曼体系结构,操作系统,进程,PCB,进程状态,僵尸进程,孤儿进程_第10张图片
 
   •    父子进程是相互独立的

ps -ef | grep ./main 可查看子进程的父进程

在这里插入图片描述

5. 僵尸进程&僵尸状态

僵尸进程的产生:

子进程先于父进程退出,子进程在退出的时候,会告诉父进程,但父进程没有来得及回收子进程的资源,导致子进程的PCB没有被释放,就产生了僵尸进程,该进程对应的状态叫僵尸状态

测试如下:

创建一个test.c
 
如下代码父进程永远不退出(里面设置了死循环),子进程执行完代码就退出Linux-冯诺依曼体系结构,操作系统,进程,PCB,进程状态,僵尸进程,孤儿进程_第11张图片
使用命令ps aux | grep test查看test的进程信息,如下图所示PID为2337的进程为一个僵尸进程在这里插入图片描述

僵尸进程的危害:

子进程的PCB没办法得到释放,想到与内存泄漏

解决办法:
kill命令
• kill + PID :杀死进程
• kill -9 + PID:强制杀死进程
但以上命令并不能杀死僵尸进程

•    重启操作系统,代价大,不推荐
•    杀掉僵尸进程的父进程,代价相对大,不推荐
进程等待-进程控制(后面讲),推荐的方式

6. 孤儿进程

孤儿进程的产生:

父进程先于子进程退出,子进程会被1号进程领养,子进程在退出的时候,就会由1号进程回收子进程的退出资源;称这种进程为孤儿进程
 
注意: 进程状态中没有孤儿状态

什么是1号进程

操作系统启动时产生的第一个进程是1号进程

测试如下:

如下代码子进程永远不退出(里面设置了死循环),父进程执行完代码就退出Linux-冯诺依曼体系结构,操作系统,进程,PCB,进程状态,僵尸进程,孤儿进程_第12张图片
如下图所示PID为7082的进程为一个孤儿进程
Linux-冯诺依曼体系结构,操作系统,进程,PCB,进程状态,僵尸进程,孤儿进程_第13张图片

6.1 问题1:

创建出来的子进程是从fork之后代码运行还是从fork之前的代码开始运行?

Linux-冯诺依曼体系结构,操作系统,进程,PCB,进程状态,僵尸进程,孤儿进程_第14张图片
父进程在执行fork时程序计数器中保存的的是下一条语句(判断语句),fork子进程,子进程拷贝父进程PCB是程序计数器中也保存到下一条判断语句,所以子进程从判断语句开始,子进程是从fork之后的代码运行

6.2 问题2:

到底是父进程先运行还是子进程选运行?

这是不确定的,取决于操作系统的内核的调度(谁先拿到CPU资源)
若有两个CPU,可能父子进程同时运行
若只有一个CPU,取决于谁先拿到CPU资源谁先运行

你可能感兴趣的