Linux进程(一)---深入了解进程的概念及状态

news2024/12/24 21:54:41

目录

什么是进程

如何管理进程

描述进程

PCB到底是什么?

PCB的内容分类

组织进程 

查看进程

ps命令

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

getpid()

getppid()

通过系统调用创建进程-fork初识

进程状态

运行态(R)

阻塞态(S)

阻塞态

 挂起态

和就绪态的区别

停止状态(T)

僵尸状态(Z)


什么是进程

进程我们虽然没有特地讲过,但是平常我们也一定在时刻接触着.例如打开任务管理器.

这些都是进程,例如QQ,浏览器,壁纸软件等,这些都是一个进程.

也是说:我们启动一个软件,本质就是启动了一个进程.

在Linux下,运行一条命令或者./xxx,其实都是在系统层面创建了一个进程.

进程概念:

课本概念:程序的一个执行实例,正在执行的程序等.

内核观点:担当分配系统资源(CPU时间,内存)的实体.

如何管理进程

Linux是可以同时加载多个程序,即Linux是可以同时存在大量的进程在系统中的.

我们必须把这些进程管理起来,如何管理呢?

先描述,再组织。

我非常建议大家可以看看我上一章所讲的内容,什么是先描述后组织,举了我们一些常见的例子来类比讲解,大家看完上一章再来看这些,看待问题的角度会有很大的不同.

描述进程

大家先来简单理解下这张图:

磁盘中有很多可执行程序,我们知道要运行程序必须先加载到内存,注意是把文件(可执行程序本质就是个文件)的内容(代码+数据)加载到内存, 为了以后方便管理,我们在操作系统内部,定义了一个结构PCB用来描述这个进程的全部属性数据.

注意,这个属性数据和文件内容关系不大.

所以此时的任务从对进程的管理,变成了对PCB结构体链表的增删查改.

所以此时再对进程有一个更深层次的定义.

进程 = 对应的代码和数据 + 进程对应的PCB结构体.

之前一直说PCB,那么这

PCB到底是什么?

我们知道这是用来描述一个进程的全部属性信息的,当有一个新的可执行文件加载到内存时,对应的PCB也会新加载一份.

进程信息被放在一个叫做进程控制块(PCB)的数据结构中,可以理解为进程属性的集合。
课本上称之为PCB(process control block),Linux操作系统下的PCB是: task_struct.

在Linux中描述进程的结构体叫做task_struct,每个系统平台的叫法可能不一样.,但统称为PCB.
task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息.

PCB的内容分类

这是PCB里面的的一些属性信息,我们会在后面分别讲解对应的重点部分.

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

组织进程 

我们前面说了,描述进程的属性信息是PCB,在Linux下叫做task_struct.

所有运行在系统里的进程都是以task_struct双链表的形式存在内核里.

对进程的操作转化为对链表进行操作.

查看进程

有三种方式可以查看,分别为

ls /proc/进程PID【以文件的方式查看进程】

ps

top【top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程资源占用状况】

这三个命令.我们一般使用ps来查看

ps命令

ps 命令用于显示当前进程的状态,类似于 windows 的任务管理器。

用法如下:

ps [options]

常用选项ajx.意思就是显示全部进程信息.

 我们写一份源文件,命名为myproc.c

输入以下内容:

 即创建一个死循环。然后复制一个窗口,一个窗口执行,另一个窗口监视该进程. 

因为ps ajx是显示所有进程,所以我们需要在后面加上grep来挑选出我们需要的进程:

ps -ajx | grep 'myproc'

这样我们发现右边程序在运行的时候,左边也能看到对应程序运行的状态.

那么多进程,我们该怎么标识唯一呢?

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

每个进程都会有一个id,我们称之为PID,用来标识自身.还有一个PPID,是用来表示该进程的父进程的ID.后面会讲.

调用函数:getpid().

getpid()

我们看一下用法:

 其中pid_t是一种数据类型,代表无符号整数.

我们简单使用一下,打开myproc.c文件,输入:

 

然后和刚才的操作一样,编译成功文件后,复制一个窗口,然后一个窗口运行,另一个窗口监视.

 这样程序便获取到了自己的pid并输出了出来.

我们如果此时想关掉这个运行程序可以怎么做呢?

1.Ctrl+C   2.kill -p PID

一号不用多说,看下第二种方法效果.

 这样运行中的进程就被kill掉了,这个后面再讲.

除了可以获取子进程ID,也可以获得父进程的ID.用法同上,只不过是getppid().

getppid()

我们在原文件中加上这个用法:

 然后相同的操作:

 

此时自身的id和父进程的id都获取到了,那么有一个问题,这个父进程是谁呢?

 

我们发现父进程是bash,那这bash是什么呢?

bash是一个命令处理器, 运行在文本窗口中, 并能执行用户直接输入的命令.

通过系统调用创建进程-fork初识

我们先看一下fork是什么.

 可以看到fork作用是创建一个子进程.然后看一下返回值.

 说如果成功的话,子进程的PID会返回给父进程,0返回给新创建的子进程.

如果失败的话,-1会被返回给父进程,没有子进程会被创建.

这就很不符合常规了,哪有一个函数有两个返回值的?

我们可以看一下下面的代码:

 编译运行:

 发现一个printf竟然输出了两次,而且还是两个返回值各不一样.

其实这是因为父进程遇到fork()之后新加了一个子进程,两个进程都经过这个printf,导致输出了两次,一次是返回给父进程的子进程PID,另一个是子进程自己拿到的0.

 相当于由一个执行流变成了两个执行流.

然而我们在真正使用的时候都是会分模块的,子进程执行自己的任务,父进程执行它自己的任务,这样互不干扰.

 因为如果创建成功,子进程id会等于0,这样会走第二个if,而父进程会得到子进程id,一定是大于0的,所以会走第三条if.

这样可以看到确实走了不同的分支了. 

还是在总结一下,为什么fork()会有两个返回值?

1.因为fork()内部,父子会各自执行一次return语句,返回了两次当然有两个返回值.

2.返回两次,并不意味着会保留两次.(比如用同一个id判断,怎么可能做到判断两次,每次都是不同的值呢(同一个id怎么可以走两个执行流)这个问题后面会说.        

fork()子进程被创建出来之后,哪个进程先执行呢?

这个不一定,谁先运行,这个是由操作系统调度器决定的.

关于fork()的认识大家可以先停到这里,后面会再次深入讲解原理.

进程状态

进程一共有5种状态:

  1. 运行状态(Running):进程正在运行或者正在等待CPU资源。

  2. 就绪状态(Ready):进程已经准备好运行,但是还没有得到CPU资源。

  3. 阻塞(可中断睡眠)状态(Sleeping):进程正在等待某个事件的发生,例如等待输入输出完成、等待信号量、等待锁等。

  4. 停止状态(Stopped):进程被暂停了,例如由于收到了SIGSTOP信号。

  5. 僵尸状态(Zombie):进程已经结束了,但是其父进程还没有来得及处理它的退出状态信息,因此它被称为僵尸进程。

这是它们之间的关系图:

下面是状态转化的几种场景:

就绪->运行:进程调度
运行->就绪:时间片到或者被强行占用
运行->阻塞:请求服务后等待响应,或者等待某个信号的到来
阻塞->就绪:请求的服务已经完成,或者等待的信号已经到来

我们将分别讲解它.

运行态(R)

运行状态(Running):进程正在运行或者正在等待CPU资源。

注意,运行态不一定是在运行,linux下 task_struct结构体只要在运行队列(调度队列)中排队,就叫做运行态.

就好比在食堂,你在排队打饭,当别人问你在干什么,你会说我在吃饭,但此时饭并没有真正到嘴里.就是这个意思.

阻塞态(S)

阻塞态

阻塞状态(Waiting):进程正在等待某个事件(非CPU资源)的发生,例如等待输入输出完成、等待信号量、等待锁等。

我们首先要知道,系统中是一定 存在各种资源的(不仅仅是CPU),还有网卡,显卡,磁盘等设备.

所以系统中不只是存在一种队列!不只有CPU的运行队列,还有磁盘,网卡等相关队列.

例如CPU有一个运行队列在运行,磁盘也有一个队列也有很多进程在准备访问磁盘.此时CPU正在执行的这个进程遇到fread需要到磁盘中读取数据,这个时候便把这个进程从CPU的运行队列放到磁盘的等待队列中,这个等待的过程就叫做阻塞态 ,这个等待的队列就叫做阻塞队列.

 挂起态

当内存不足的时候,OS通过适当的置换进程的代码和数据到磁盘,进程的状态就叫做挂起.

当进程处于挂起态时,它暂时放弃了CPU的执行权,将进程的状态标记为“不可执行”。这通常是因为进程需要等待某些事件的发生,例如:I/O操作,信号接收,资源不足等等.

当进程是挂起态时,内存内部只有task_struct这个结构体,而没有代码和数据.

我们一开始提到了,这个阻塞态又叫做可中断睡眠状态.什么叫可中断睡眠态呢?

看下面代码:

我们让这段程序休眠100秒,然后运行,另一个窗口观察.

 

 此时发现程序进入了睡眠状态,此时我们给它发送信号,让它醒过来.

发送19号信号之后,就发现状态改变了,说明还是“理你的”.

就是说你给它信号,它还会回你,就类似于我在睡觉,有事随时叫醒我.这就是可中断睡眠.

与此对应的是D状态(磁盘休眠状态),又叫做深度睡眠状态,这是不可被唤醒的.类似于我在睡觉,有事勿扰.

和就绪态的区别

就绪态(Ready State)是指进程已经准备好执行,并满足了调度所需的所有条件,包括获取所需的资源。在就绪态中,进程等待被调度执行,但并没有获得CPU的执行权。它处于一种可以立即执行的状态,只需等待系统调度器将其选中并分配CPU的执行时间。

等待态(Waiting State)是指进程暂时无法执行,因为它正在等待某些事件、条件或资源的发生。进程进入等待态时,它放弃了CPU的执行权,并等待外部事件的触发或者特定条件的满足。在等待态中,进程暂时不能再进行任何运算,直到等待的事件或条件发生,或者所需的资源可用。

总的来说,就是就绪态资源已经准备就绪,就等被调用;等待态是因为资源没有就绪,然后放弃了被调用.

停止状态(T)

停止状态(Stopped):进程被暂停了,例如由于收到了SIGSTOP信号。

通常,暂停态用于暂停或中止进程的执行,例如在调试过程中暂停某个进程以进行调试操作,或者由系统管理员在必要时暂停进程的执行。进程可以从暂停态恢复到就绪态,并继续执行它原来被暂停的操作。

需要注意的是,暂停态与挂起态(睡眠/阻塞态)不同。挂起态表示进程暂时无法执行,等待某些条件或事件的发生。而暂停态是人为操作或特定信号导致进程主动停止执行,暂时中止进程的运行。

等待接收到对应的信号(如 SIGCONT)或使用命令(如 kill -CONT <pid>)来恢复到就绪态。

僵尸状态(Z)

僵尸状态(Zombie):进程已经结束了,但是其父进程还没有来得及处理它的退出状态信息,因此它被称为僵尸进程。

僵尸进程的主要特点是进程已经结束执行,但是相关的资源并没有完全释放,包括进程的PCB、内存和其他打开的文件描述符等。尽管僵尸进程不再执行,但其存在占用了系统的一些资源。

 可以看到子进程睡眠5秒就会结束离开,而父进程一直在运行,这个时候便会出现僵尸进程.

 可以发现子进程变成了Z僵尸状态,Z+代表是前台运行程序.

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

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

相关文章

【UE4 C++】07-角色运动设置

效果 可以看到我们可以通过WASD控制角色前后左右移动&#xff0c;通过鼠标控制摄像机旋转朝向。 步骤 1.在虚幻商城中搜索“Gideon”&#xff0c;将该免费资源添加到工程中&#xff08;大概2.6G&#xff09; 2. 打开之前创建的“PlayerCharacter” 选中网格体组件&#xff0…

华为OD机试真题 Java 实现【不开心的小朋友】【2023 B卷 100分】,附详细解题思路

目录 一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 大家好&#xff0c;我是哪吒。 做技术&#xff0c;我是认真的&#xff0c;立志于打造最权威的华为OD机试真题专栏&#xff0c;帮助那些与我有同样需求的人&#xff…

C# 参数传递(引用类型参数)

目录 一&#xff0c;引言 二&#xff0c;引用类型参数作为值参数传递 三&#xff0c;引用类型参数作为引用参数传递 一&#xff0c;引言 方法中参数的传递方式主要有值参数传递和引用参数传递&#xff08;ref&#xff0c;out&#xff09;&#xff0c;而参数有可以分为值类型…

巩固一下NodeJs

1、初始化(确保当前电脑有node环境) npm init 2、安装express npm i expressnpm i ws文件结构 3、编写相关代码启动node服务(server.js) //导入下列模块&#xff0c;express搭建服务器&#xff0c;fs用来操作文件、ws用来实现webscoket const express require("expr…

使用halcon深度学习实现缺陷检测

使用halcon深度学习实现缺陷检测 前言 Halcon是一种功能强大的机器视觉库&#xff0c;提供了许多用于图像处理和分析的工具和算法。它也集成了深度学习算法&#xff0c;可以用于缺陷检测和其他视觉任务。下面是一些使用Halcon深度学习算法实现缺陷检测的步骤&#xff1a; 1.…

写好“提示”改变“智造未来”-GPT4提示词驶入代码优化驾驶座心得

开篇 在前端科技的新浪潮中,Artificial Intelligence (AI)的逐渐成熟与发展引领着我们向前。其中OpenAI的GPT4提供了我们一种新的可能,帮助我们优化代码,使编程变得更加轻松。在这篇文章中,我们将一同探究如何在1-2分钟内,依靠GPT的提示词优化我们的代码,并展现出我们在…

F - Weight of the System of Nested Segments - 思维+排序

分析&#xff1a; 将每个点的权重以及坐标存下来&#xff0c;按权重排序&#xff0c;找出前n个点然后按坐标排序&#xff0c;再按要求输出最大区间到最小区间。 代码&#xff1a; #include <bits/stdc.h>using namespace std;typedef long long ll; typedef pair<in…

Python高频面试题——如何实现列表去重

在招聘Python自动化测试岗位面试时&#xff0c;最常问的一个编码实战问题就是&#xff1a; 一个包含多个值的列表&#xff0c;但存在重复值&#xff0c;如何实现去重&#xff1f;当然大家也可以结合实际业务情况进行提问&#xff0c;例如&#xff1a;统计今天有多少个不同的用…

Day51|309.最佳买卖股票时机含冷冻期 、714.买卖股票的最佳时机含手续费

309.最佳买卖股票时机含冷冻期 1.题目&#xff1a; 给定一个整数数组prices&#xff0c;其中第 prices[i] 表示第 i 天的股票价格 。​ 设计一个算法计算出最大利润。在满足以下约束条件下&#xff0c;你可以尽可能地完成更多的交易&#xff08;多次买卖一支股票&#xff0…

电脑如何提高图片dpi分辨率?在线修改图片dpi的操作方法

想要给微信换个背景图片&#xff0c;但是又发现像素尺寸不合适&#xff0c;需要调整图片大小&#xff08; https://www.yasuotu.com/size&#xff09;&#xff0c;那么怎么可以修改图片大小呢&#xff1f;今天分享的这款图片处理工具可以快速将图片大小修改&#xff0c;一起来看…

线性代数 4 every one(线性代数学习资源分享)

Linear Algebra 4 Every One 版权说明&#xff0c;以下我分享的都是一个名叫Kenji Hiranabe的日本学者&#xff0c;在github上分享的&#xff0c;关于Gilbert Strang教授所撰写的《Linear Algebra for Everyone》一书的总结&#xff0c;更像是一个非常精美的线性代数手册&#…

深入解析 MQTT 中基于 Token 的认证和 OAuth 2.0

除了前几篇文章中提到的认证方法&#xff0c;本文将对其他认证方法进行深入分析和探讨。 具体而言&#xff0c;我们将深入了解基于 Token 的认证和 OAuth 2.0&#xff0c;阐述它们的原理并展示它们在 MQTT 中的应用。 基于 Token 的认证 让我们先来认识一下基于 Token 的认证…

网站窗口标题旁的图标生成与替换

电脑端浏览器打开网站后窗口顶部的标签标题左边会有一个网站图标的显示&#xff0c;那个图标需要的是 .ico 格式的文件 在线免费生成ico图标的网址 只需要打开网址选择文件、选择尺寸生成下载&#xff0c;然后放到个人项目中&#xff08;一般放在public目录中&#xff09;&am…

IDEA中右侧栏和底部栏不见了

IDEA中右侧栏和底部栏不见了 在开发中&#xff0c;IDEA的右侧栏目maven、database等栏目不见了 右侧栏中和底部没东西。 问题解决&#xff1a; View—>Appearance–>Tool Windows Bars 选中即可。 选中之后&#xff0c;出现

mac安装Golang开发环境及快速入门

目录 一、Mac brew 安装go环境 1.1 安装步骤 1.2 设置GOPATH 及环境变量 1.3 编写第一个go程序 二、快速入门 1.1 快速入门需求 1.2 go学习&#xff08;自用&#xff09; 一、Mac brew 安装go环境 1.1 安装步骤 1&#xff09;终端输入&#xff0c;也可以指定下载go版本…

黑客(信息安全网络安全)自学手册

一、自学网络安全学习的误区和陷阱 1.不要试图先成为一名程序员&#xff08;以编程为基础的学习&#xff09;再开始学习 行为&#xff1a;从编程开始掌握&#xff0c;前端后端、通信协议、什么都学。 缺点&#xff1a;花费时间太长、实际向安全过渡后可用到的关键知识并不多。…

uniapp自定义头部,计算状态栏和导航栏高度超简单三步

效果图 1.pages.json 页面给要自定义头部的页面加入一行代码 "navigationStyle":"custom" {"path": "pages/index/index","style": {"navigationBarTitleText": "","navigationStyle":"…

代码随香录day16

104. 二叉树的最大深度 思路&#xff1a;这道题推荐用层序遍历递归的方式 递归三要素&#xff1a; 终止条件&#xff1a;当当前node为空时候 单层递归逻辑&#xff1a;分别向node的左子树和右子树进行递归&#xff0c;定义left和right接受返回值 递归参数&#xff1a;root 代…

wincc与300以太网通讯教程在建材行业矿粉磨生产自动化控制系统中应用

内容摘要 上位机与S7-300PLC通信采用以太网通信&#xff0c;通讯模块采用捷米特ETH-S7300-JM01以太网通讯模块&#xff0c;捷米特ETH-S7300-JM01通讯模块直接插到CPU315-2DP的DP口上。 项目介绍 立磨PLC控制系统&#xff1a; 立磨是一种理想的大型粉磨设备&#xff0c;广泛应…

最详细的下载安装PicGo图床配合Typora使用

1.node.js下载安装1.2 检验安装成功 2. PicGo下载安装3. 配置Gitee【配合PicGo使用】3.1 获取PicGo的token 4. 配置PicGo4.1 下载插件4.2 配置图床[Gitee]4.3 配置Typora 5. 上传图片到Gitee【重要】6.解决配置错误 1.node.js下载安装 【node.js下载链接】点击跳转页面&#x…