进程的概念

一.进程和程序的理解

首先抛出结论:进程是动态的,暂时存在于内存中,进程是程序的一次执行,而进程总是对应至少一个特定的程序。

程序是静态的,永久的存在于磁盘中

程序是什么呢?程序其实就是存放在我们磁盘上的可执行程序,它静态的,而且是永久存在的。

image-20240705150158608

进程就是磁盘上的程序,加载拷贝到内存上运行起来的,这就是进程。

image-20240705151023097

在windows上打开任务管理器,我们就可以看到操作系统中运行的所有的进程。

image-20240705150530296

这里存在着很多进程,这么多进程,操作系统要不要将这些进程给管理起来呢?答案是肯定的。那又要如何管理呢?这就引出了之前说的冯诺依曼体系结构中的,先描述,再组织

那要怎么将这些进程描述好,组织好呢?首先操作系统是C语言写的,C语言中描述一个物体的很多属性,都是通过结构体struct概括起来的。而描述进程的这个结构体的全部叫做:PCB。

二.进程的PCB

进程的PCB全称叫做进程控制块(process control block),PCB中部分内容如下:

struct xxxx
{//id(也就是pid)//代码数据地址//优先级//程序计数器(pc)//struct PCB*next
}

标示符:描述本进程的唯一标示符,用来区别其他进程。(pid)
状态:任务状态,退出代码,退出信号等。
优先级:相对于其他进程的优先级。
程序计数器:程序中即将被执行的下一条指令的地址。(pc)
内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针。
上下文数据:进程执行时处理器的寄存器中的数据。
I/O状态信息:包括显示的I/O请求,分配给进程的I/O设备和正在被进程使用的文件列表。
记账信息:可能包括处理器时间总和,使用的时钟总数,时间限制,记账号等。
其他信息等等……

进程的运作:

在这里插入图片描述

所以说:进程=可执行程序+内核数据结构(PCB)。

在Linux中,进程的PCB具体是struct task_struct{}

其中可执行程序已经被描述成了PCB,然后操作系统需要将PCB给组织起来,使用链表进行链接,于是对于进程的管理就成了对链表的增删改查。

这里的链表又和之前学习的双向头尾链表有点不同。

struct task_struct//PCB
{//各种属性struct dlist list;
}
struct dlist//链表
{struct dlist*prev;struct dlist*next;
}

PCB中有一个结构体对象list,然后该结构体中有prev和next指针将操作系统中PCB给组织起来。

image-20240705162447957

这里不要认为进程的PCB只能存在链表中,操作系统中存在许多组织进程PCB的列表,像运行队列,阻塞队列等等。

后续细说。

三.task_struct中的pid和ppid

1.pid

task_struct中有很多属性,也就是很多字段,那它的核心字段有哪些呢?-贯彻整个的学习的过程。

这里我要说到一个核心字段pid(process id),也就是标识该进程的一个数字,表明它是独一无二的一个进程。

这里我们写一个小小的代码来看看进程的pid。

①test.c文件中,写一个死循环的程序。

#include<stdio.h>                                                                                #include<unistd.h>
int main()
{while(1){printf("这是一个进程\n");sleep(1);}return 0;}

②makefile自动化构建代码。

mycode:test.cgcc -o $@ $^
.PHONY:clean
clean:rm -f mycode     

然后我们使用make创建出可执行程序,然后执行该可执行程序,于是该可执行程序就变成了进程。

image-20240705182716557

这里鼠标右键,点击复制SSH渠道,为了方便我们观察进程的运行和进程的pid的变化。

使用脚本查看该进程的pid:ps ajx | head -1 && ps ajx | grep mycode

image-20240705183213406

该进程我们写的死循环,它就在一直运行起来的,每次我们使用这个这个脚本查看进程,可以看出mycode进程的pid一直没变过,因为该进程一直在运行。而每次使用该脚本,我们都会使用grep这个程序,一瞬间,grep进程就运行起来并马上死亡,于是看到每次grep,它的pid都会发生变化。

在左边进程一直在运行,可以使用ctrl+c,终止该进程,再使用该脚本查看,就发现该进程pid就看不到了。

还可以使用这个命令来杀死进程:kill -9 进程的pid(无脑杀死进程,后续说的僵尸进程没有办法杀死)

image-20240705183936835

2.ppid

这里可以看到除了进程的pid之外,进程还有ppid,而且ppid的值一直没有变过。

解释:进程中除了自己的pid之外,还有父进程的pid,父进程的pid,在子进程来看就是自己的ppid。

那这个父进程到底是谁呢?父进程其实是bash,也就是我们的命令行解释器。

bash是一直不变的,我们在bash下创建的进程,都是bash的子进程。

马上我们使用函数getpid()和getpppid()就验证了。

四.系统调用接口getpid()和getppid()

上述中,我们使用脚本来查看一个进程的pid,每次都这样子来查看进程的pid就很麻烦,于是有两个系统调用接口就可以直接查看进程的pid和ppid,现在我们直接演示。

注意系统调用接口函数在man 2号手册里面查找,而各种库函数都是在man 3号手册中查找的。

image-20240705190657300

修改源代码:

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{while(1){printf("这是一个进程,pid:%d,ppid:%d\n",getpid(),getppid());sleep(1);}                                                                                       return 0;
} 

image-20240705192328849

这里即验证成功,该进程的ppid和bash进程的pid是对应上的,故而说明,在bash下创建出来的进程都是bash的子进程。

五./proc/pid目录和PCB的关系

linux中有一个目录proc,它存放着所有的进程。

image-20240705200132515

其中proc/pid目录存放着具体某个进程的一些信息。目录的名称就是以该进程的pid命名的。

image-20240705200930739

当我们将进程启动起来,使用ls /proc/pid命令就可以查看该进程的一些信息。

其中cwd就是该进程的当前工作目录,而exe就是可执行程序,还有很多信息。


image-20240705201301015

当ctrl+c终止掉进程之后,再使用查看同样的目录,该目录就不存在了,由此可以看出,/proc目录结构是动态的


当进程运行起来的时候,我们使用命令make clean将可执行程序删除了(也就是在磁盘上删除了该可执行文件),但是进程此时并不受影响,因为进程已经在内存中运行起的。

然后使用命令查看该进程的信息,可以看到该进程是知道自己的可执行程序是被删除了的。

于是得出一个结论:进程是可以找到自己的可执行程序的,靠的就是cwd这个链接文件。

image-20240705201808927


在/proc/pid下我们可以看到具体某个进程的信息,那么它和进程的PCB的关系是什么呢?

/proc/pid 目录下的内容是操作系统向用户展示的关于进程的一部分信息,它与进程控制块(PCB)有一定的关联。

/proc/pid 中的信息可以被看作是从 PCB 中提取出来的、以可读形式呈现给用户的部分关键数据。这些数据反映了进程的某些状态和特征,是 PCB 中部分重要信息的外在表现。

③例如,/proc/pid/status 文件中的一些字段可能与 PCB 中记录的进程状态信息相对应;/proc/pid/maps 可能与 PCB 中关于进程内存布局的信息相关。

然而,/proc/pid 并不能涵盖 PCB 中的所有详细和底层的控制信息,只是提供了一个便于用户观察和了解进程基本情况的接口。

六.Linux中创建进程的两种方式

1.手动的创建进程

上述的所有过程我们都是手动的创建出进程。

除了手动的创建出进程,我们还可以使用代码来创建出进程。

2.使用代码进行创建

使用函数fork()来创建出子进程。(后续细说)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/41583.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图像分类-数据驱动方法

K近邻算法&#xff08;K-Nearest Neighbors&#xff0c;简称KNN&#xff09; KNN算法通过比较新样本与训练集中的样本的距离&#xff0c;然后根据最近的K个邻居的投票结果来决定新样本的分类。 如图所示&#xff0c;K越大的边界会更加平滑&#xff0c;本质上是根据某一样本最近…

红薯小眼睛接口分析与Python脚本实现

文章目录 1. 写在前面2. 接口分析3. 算法脚本实现 【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Py…

04.27 - 05.18_111期_Linux_进程间通信

命名管道通信 特点&#xff0c;写端在没有往管道里面写内容时&#xff0c;读端会处于阻塞状态 共享内存 特点&#xff0c;读端在什么时候都可以进行读操作 &#xff0c;拷贝次数少&#xff0c;通信次数快 makefile 中使用g进行编译 要实现将上述两个特点进行融合&#xff…

Microsoft Copilot Studio:定制 AI 解决方案的未来

微软最近为其生成式 AI 和大型语言模型工具套件添加了一项创新功能&#xff0c;即 Copilot Studio。这款新产品在 Microsoft Ignite 2023 大会上亮相&#xff0c;将彻底改变组织与 AI 助手的互动方式。 为每个用户提供定制能力 Copilot Studio 是一款出色的用户友好型平台&am…

【面试题】Reactor模型

Reactor模型 定义 Reactor模型是一种事件驱动的设计模式&#xff0c;用于处理服务请求。它通过将事件处理逻辑与事件分发机制解耦&#xff0c;实现高性能、可扩展的并发处理。Reactor模型适用于高并发、事件驱动的程序设计&#xff0c;如网络服务器等。 特点 事件驱动&#…

递归(三)—— 初识暴力递归之“字符串的全部子序列”

题目1 &#xff1a; 打印一个字符串的全部子序列 题目分析&#xff1a; 解法1&#xff1a;非递归方法 我们通过一个实例来理解题意&#xff0c;假设字符串str “abc”&#xff0c;那么它的子序列都有那些呢&#xff1f;" ", “a”&#xff0c; “b”&#xff0c;…

Vue的民族民俗文化分享平台-计算机毕业设计源码22552

基于Vue的民族民俗文化分享平台设计与实现 摘 要 本文介绍了一种基于Vue.js前端框架和Express后端框架的民族民俗文化分享平台的设计和实现。该平台旨在通过线上方式&#xff0c;促进民族民俗文化的传播与分享&#xff0c;增强公众对多元文化的了解和认同。 平台为普通用户提供…

图论·题解1

原题地址 P3371 【模板】单源最短路径&#xff08;标准版&#xff09; 注意的点&#xff1a; 边有重复&#xff0c;选择最小边&#xff01;对于SPFA算法容易出现重大BUG&#xff0c;没有负权值的边时不要使用&#xff01;&#xff01;&#xff01; 70分代码 朴素板dijsktra…

前后端的导入、导出、模板下载等写法

导入&#xff0c;导出、模板下载等的前后端写法 文章目录 导入&#xff0c;导出、模板下载等的前后端写法一、导入实现1.1 后端的导入1.2 前端的导入 二、基础的模板下载2.1 后端的模板下载-若依基础版本2.2 前端的模板下载2.3 后端的模板下载 - 基于资源文件读取2.4 excel制作…

JVM8为什么要增加元空间 ?

持久代 持久代的大小 为什么移除持久代 &#xff1f; 元空间 元空间的特点&#xff1a; 持久代 持久代中包含了虚拟机中所有可通过反射获取到的数据&#xff0c;比如Class和Method对象。不同的Java虚拟机之间可能会进行类共享&#xff0c;因此持久代又分为只读区和读写区。…

24西安电子科技大学马克思主义学院—考研录取情况

01、马克思主义学院各个方向 02、24马克思主义学院近三年复试分数线对比 PS&#xff1a;马院24年院线相对于23年院线增加15分&#xff0c;反映了大家对于马克思主义理论学习与研究的热情高涨&#xff0c;也彰显了学院在人才培养、学科建设及学术研究等方面的不断进步与成就。 6…

直接更新flowable数据库的流程定义信息的一种方法

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; h…

文章解读与仿真程序复现思路——太阳能学报EI\CSCD\北大核心《绿电交易场景下计及温控负荷的高铁站两阶段调度策略》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

【第21章】MyBatis-Plus多数据源支持

文章目录 前言一、dynamic-datasource1. 特性2. 约定3. 使用方法3.1 引入依赖3.2 配置数据源3.3 使用 DS 切换数据源 二、mybatis-mate1.特性2.使用方法2.1 配置数据源2.2 使用 Sharding 切换数据源2.3 切换指定数据库节点 三、实战1. 引入库2. 配置3. 使用 DS 切换数据源4. 测…

开关电源详解

一、开关电源的概述 1. 定义与简介 开关电源&#xff08;Switched-Mode Power Supply&#xff0c;SMPS&#xff09;是一种通过高频开关器件&#xff08;如晶体管、MOSFET&#xff09;进行电能转换的电源装置。与传统的线性电源相比&#xff0c;开关电源具有转换效率高、体积小…

vue项目打包部署后 浏览器自动清除缓存问题(解决方法)

vue打包部署后 浏览器缓存问题&#xff0c;导致控制台报错ChunkLoadError: Loading chunk failed的解决方案 一、报错如下&#xff1a; 每次build打包部署到服务器上时&#xff0c;偶尔会出现前端资源文件不能及时更新到最新&#xff0c;浏览器存在缓存问题&#xff0c;这时在…

Pandas数据可视化详解:大案例解析(第27天)

系列文章目录 Pandas数据可视化解决不显示中文和负号问题matplotlib数据可视化seaborn数据可视化pyecharts数据可视化优衣库数据分析案例 文章目录 系列文章目录前言1. Pandas数据可视化1.1 案例解析&#xff1a;代码实现 2. 解决不显示中文和负号问题3. matplotlib数据可视化…

ListBox自动滚动并限制显示条数

1、实现功能 限制ListBox显示的最大条数&#xff1b; ListBox自动滚动&#xff0c;显示最新行&#xff1b; 2、C#代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using Syst…

JUC并发编程基础(包含线程概念,状态等具体实现)

一.JUC并发编程基础 1. 并行与并发 1.1 并发: 是在同一实体上的多个事件是在一台处理器上"同时处理多个任务"同一时刻,其实是只有一个事件在发生. 即多个线程抢占同一个资源. 1.2 并行 是在不同实体上的多个事件是在多台处理器上同时处理多个任务同一时刻,大家…

【C++】main函数及返回值深度解析

一.main函数介绍 1.main函数怎么写 #include <iostream>int main() {// 程序的代码放在这里std::cout << "Hello, World!" << std::endl;return 0; }在这个例子中&#xff1a; #include <iostream> 是预处理指令&#xff0c;它告诉编译器…