Linux——进程概念

什么是操作系统

操作系统管理各种计算机硬件、为应用程序提供基础、并且充当计算机硬件与用户之间的中介。

冯诺依曼体系

这里的存储器指的是内存不考虑缓存情况,这里的CPU能且只能对内存进行读写,不能访问外设(输入或输出设备)外设(输入或输出设备)要输入或者输出数据,也只能写入内存或者从内存中读取。

举例:使用printf输出hello world在计算机内部是如何执行的,首先,键盘上编写C语言文件,然后再载入到内存中运算器和控制器对该文件进行处理(忽略处理细节,然后再执行C语言文件把hello world输出到屏幕上

操作系统如何对软硬件资源进行管理:

操作系统对硬件做管理一句话--先数据结构再算法,对软硬件资源建立数据结构模型,再对该模型设计算法实现管理

如何理解进程?

在多道程序环境下,允许多个程序并发执行,此时它们将失去封闭性,并具有间断性及不可再现性的特征。为此引入了进程的概念,以便更好地描述和控制程序的并发执行,实现操作系统的并发性和共享性

  1. 间断性:并发程序具有"执行-暂停--执行"这种间断性的活动规律。
  2. 失去封闭性:多个程序共享系统中的资源,这些资源的状态将由多个程序来改变,致使程序之间相互影响。
  3. 不可再现性:在初始条件相同的情况下,程序的执行结果依赖于执行的次序。程序执行的结果不确定。如何理解?在windows中你用的软件运行起来都叫进程,你将一张图片发给的好友a,这是你使用软件的结果,这个结果取决于你。而不是取决于程序。
  4. 并发性:多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为 并发

PCB(Process Conctrl Block)

可以简单理解为一个记录进程属性的集合(是一个C语言结构体)

举例:使用printf输出hello world在计算机内部是如何执行的,首先,键盘上编写C语言文件,然后再载入到内存中运算器和控制器对该文件进行处理(忽略处理细节),然后再执行C语言文件把hello world输出到屏幕上,现在多一个hello linux的程序。会怎么样去执行。

先简单的讲述一下:首先,会对两个程序生成两个对应的PCB结构体,并且里面包含我们编写的代码和数据(如何连接、存储暂不深究),所以一个进程 = PCB + 该进程代码和数据。这样操作系统才可以分辨出那个是hello world,hello linux。以及执行后续操作。

注意:在linux中的PCB被定义为task_struct,他不是单纯的一种结构,而是多种结构嵌合,这里先理解为链式结构

查看进程

Linux中的/proc目录中存放着每一个进程目录和内核文件

Linux系统中查看父进程ID,进程ID,进程组ID,会话ID的方法:ps ajx

我们可以输入ps ajx指令看到对应进程的pid(每一个进程独有的id,相当于他们的身份证号码)

  1. PID:进程ID,是Linux操作系统用来唯一标识一个进程的数字。
  2. PPID:父进程ID,表示创建当前进程的父进程的ID。
  3. PGID:进程组ID,表示该进程所属的进程组的ID。
  4. SID:会话ID,表示该进程所属的会话的ID。一个会话可以包含多个进程组,而一个进程组只能属于一个会话。
  5. TTY:终端类型,表示该进程是在哪个终端上运行的。如果进程是在后台运行的,这个字段可能显示为 ?。
  6. TPGID:前台进程组ID,如果该进程是在前台运行的,这个字段表示该进程所属的前台进程组的ID。
  7. STAT:状态,表示进程的当前状态。常见的状态(后面进程状态会讲)
  8. TIME:CPU时间,表示该进程占用CPU的总时间。
  9. COMMAND:命令,表示启动该进程的命令行。PID:进程ID,是Linux操作系统用来唯一标识一个进程的数字。

每一个进程关闭后,重新开启,得到的PID是与之前的PID不一致

当程序作为进程开始执行时,会在/proc 文件夹中新建一个目录,目录的名字为该进程的PID,在该文件夹中会有两个快捷方式(暂时这么理解) exe和cwd,exe->可执行程序 cwd->当前进程的工作目录--这也解释了之前在C语言阶段中,使用fopen函数时,为什么会自动生成文件在该目录一样,是因为在进程中记录了该路径,该路径也被称为当前进程的工作路径

这里的PID是程序在运行时,在进程中对应的ID,每一次重启ID都会产生不同的ID号

这里的PPID该进程的父进程,本质是bash(什么是bash?)--(bash是shel1的一种,shel1:是一个程序用于给用户与操作系统内核进行交互的接口,它允许用户输入命令,执行程序,操作文件和目录,以及管理系统资源)

我们每一次打开xshell写指令的时候,我们的系统会给我创建bash进程,因为bash是用于对操作系统交互的接口,所有的指令、程序的父进程都是bash,只负责命令行解释给操作系统(翻译官),每一个指令或自己写的程序都是子进程,执行出问题的时候只会影响子进程。

如何创建进程?

使用fork函数创建子进程,使用./可执行文件,或者使用bash指令即可创建进程(创建进程可以理解为运行程序)

fork函数

Q1:为什么fork要给子进程返回0,给父进程返回子进程pid?

返回不同的返回值是为了区分不同的执行流,执行不同的代码,而且子进程是要被父进程管理的,他结束了要告诉父进程他结束了,不然会导致成为僵尸进程(在后面进程状态中会讲到)

Q2:一个函数是如何做到返回两次的?如何理解?

在fork函数内部实现了创建子进程,因为父子进程的代码是共享的,我们就可以像旁边的那里一下对id做if然后实现返回两个不同的值

Q3:fork函数,究竟在干什么?

1.进程 = 内核数据结构 +代码和数据

2.fork()函数后的代码是共用的在下面共用的代码中肯定有同名定义的变量,其实对于这些变量而言,系统会对他们做写时拷贝,只有子进程用到的时候才会对该数据做写时拷贝,为子进程创建多一份

为什么这里的after fork被执行两次?

是因为在fork之后,该程序创建了子进程,而子进程与父进程的代码是共用的,这样在执行父进程的时候打印了一次,执行子进程的时候又打印了一次

为什么这段代码可以同时让两个条件判断成立?

因为在fork()函数过后,就多了一个子进程而子进程的的pid返回值是0,所以子进程去执行了id==0的那一部分,而父进程执行了id>0的部分。这里不禁有一个疑问?一个变量id是如何接收两个值的呢?在后面地址空间会讲。

相关推荐
专注API从业者15 小时前
Python/Java 代码示例:手把手教程调用 1688 API 获取商品详情实时数据
java·linux·数据库·python
Ribou16 小时前
Ubuntu 24.04.2安装k8s 1.33.4 配置cilium
linux·ubuntu·kubernetes
tan180°17 小时前
Boost搜索引擎 网络库与前端(4)
linux·网络·c++·搜索引擎
Mr. Cao code17 小时前
Docker:颠覆传统虚拟化的轻量级革命
linux·运维·ubuntu·docker·容器
抓饼先生18 小时前
Linux control group笔记
linux·笔记·bash
挺6的还18 小时前
25.线程概念和控制(二)
linux
您的通讯录好友18 小时前
conda环境导出
linux·windows·conda
代码AC不AC19 小时前
【Linux】vim工具篇
linux·vim·工具详解
码农hbk20 小时前
Linux signal 图文详解(三)信号处理
linux·信号处理
bug攻城狮20 小时前
Skopeo 工具介绍与 CentOS 7 安装指南
linux·运维·centos