【Linux】进程的概念

文章目录

  • 1. 基本概念
  • 2. 进程的描述
  • 3. 进程的一些基本操作
    • 3.1 查看进程
    • 3.2 结束进程
    • 3.3 通过系统调用获取进程标示符
    • 3.4 通过系统调用来创建子进程
  • 4. 进程状态
    • 4.1 操作系统的进程状态
    • 4.2 Linux对于这些状态的处理方式

1. 基本概念

什么是进程?

在回答这个问题之前想问另一个问题:什么是程序?

  • 我们写的代码(源文件)在经过编译器编译之后生成的是文件,那么就是存放在磁盘中的。所以程序的本质就是文件,在磁盘存放

所谓的进程,就是运行着的程序,我们知道程序的运行肯定是需要CPU做运算的,CPU只能直接与内存做交互,所以程序一定要加载到内存中才能运行(这是体系结构决定的!!)。

同一时间,内存中会有很多进程,所以我们就要这些进程**管理**起来。

那么,怎么管理呢?

2. 进程的描述

在上一篇文章中我们讲到,所谓的管理就是:先描述,再组织

我们一般会采用一个结构体来描述这些进程的相关属性

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

image-20231017144945959

上面是部分内核的代码截图,实际上内核中有关task_struct的代码有很多,主要可以分为以下几类

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

抽象出来大概可以这样表示:(假设系统中进程使用链表的结构组织)

struct task_struct
{
	//进程的所有属性
    //...
  	//进程对应的代码和数据的地址
    //...
  	//下一个进程的地址
    struct task_struct* next;
};

关于task_strcut更详细的讲解,可以看一看这一篇博客:Linux中进程控制块PCB-------task_struct结构体结构(童嫣

有了上述的观念之后,我们从内核的角度来看,进程就是**内核数据结构(task_struct) + 进程对应的磁盘代码**

3. 进程的一些基本操作

3.1 查看进程

  1. 方法一:ps axj可以查看当前所有的进程

ps axj结合管道grep指令可以显示我们想要看到的进程,同时想要看到所有信息的含义,就要加上head -1表示将查询到的第一行数据也显示出来

image-20231017153523703

  1. 可以在/proc目录下查看当前所有进程

image-20231017154325799

3.2 结束进程

对于一般进程,我们可以使用**[Ctrl + c]结束,也可以使用kill**命令结束

image-20231017155140082

image-20231017155551984

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

每个进程都有一个唯一标识符:PID我们可以通过系统调getpid()用来获取这个唯一标识符

image-20231017160058629

注意:

  • 这里的getpid和getppid获取到的就是进程的标识符,其中getpid是获取进程的PID,getppid是用于获取父进程PID

  • 函数的返回值pid_t实际上就是int,只是在系统层面进行了封装

image-20231017162257157

image-20231017164705233

可以看到,我们通过 getpid() 和 getppid() 函数得到的值的确是我们进程对应的id;同时,我们发现myproc进程的父进程是 bash,即 shell 外壳,这也侧面证实了我们之前提到的结论 – shell 为了防止自身崩溃,并不会自己去执行指令,而是会派生子进程去执行

同一个程序重新被运行时它的进程id可能与之前不一样,因为它的代码和数据需要重新从磁盘中加载;但是它的父进程id一定是一样的,因为它们都是通过 bash 来执行

image-20231017164950366

3.4 通过系统调用来创建子进程

我们可以通过系统调fork来创建子进程

image-20231017165123058

image-20231017170441969

image-20231017170609253

可以看到,所有子进程的id都是0,父进程的id都是子进程的pid,这是因为fork的返回值规定:当fork执行之后将会产生两个进程,其中父进程的返回值是子进程的pid,子进程的返回值是0,fork之后的所有代码都被父子进程共有

4. 进程状态

4.1 操作系统的进程状态

在真正进入的进程状态的学习之前,大家或多或少应该听说过一些进程的状态,比如:挂起,僵尸等等,在进入的进程状态的学习之前,我们需要统一一些观点:

  1. 状态是进程内部的属性,所有的属性都在PCB里

  2. 进程不只会占用CPU资源,也有可能随时要外设资源

  • 运行状态

    进程PCB在运行队列里面的进程状态就是运行状态(不是说进程在运行时才是运行状态)

    运行队列的概念:

    CPU需要对进程做执行,同一时间操作系统内会有很多的进程,那么这些进程谁先谁后呢?此时就需要一个队列将这些进程管理起来,确定谁先执行谁后执行。这个队列里面保存的实际上并不是每个进程对应的二进制代码,而是PCB(task_struct),这个队列就是运行队列(run queue)

    每个CPU拥有一个运行队列

  • 阻塞状态

    我们在上面说到,进程不止会占用CPU资源,也可能随时需要外设资源,当一个进程在运行的过程中需要访问外设资源的时候,由于外设很慢(相对于CPU来说),所以进程需要等待外设,此时CPU就想去处理其他进程,那么当前进程就会进入到阻塞状态

    拓展一下:

    每个CPU执行一个进程,当前进程在处于阻塞状态,等待其他硬件资源的时候,实际上也就是当前进程的PCB进入到了其他硬件的run queue中,也就是说每一个硬件都拥有一个runqueue

  • 挂起状态

    如果系统中存在很多进程,当前进程短时间内不会被调度,代码和数据短时间内不会被执行,此时如果操作系统中的内存不够,就会将这些进程的相关信息保存在磁盘中,节省一部分内存。此时这些被保存在磁盘上的进程就是处于挂起状态

    挂起一定是阻塞的,阻塞不一定挂起

4.2 Linux对于这些状态的处理方式

在上一小节中我们讲到了操作系统内进程的概念性状态,那么在Linux下的表现形式是怎样的呢?

在Linux源码里面能够找到一个数组:task_state_array 罗列了Linux下所有的进程状态

/*
 * The task state array is a strange "bitmap" of
 * reasons to sleep. Thus "running" is zero, and
 * you can test for combinations of others with
 * simple bit tests.
 */
static const char *task_state_array[] = {
	"R (running)",		/*  0 */     // 运行状态
	"S (sleeping)",		/*  1 */     // 阻塞状态
	"D (disk sleep)",	/*  2 */     // 磁盘休眠状态/深度睡眠状态(了解)
	"T (stopped)",		/*  4 */     // 暂停状态
	"T (tracing stop)",	/*  8 */     // 该进程正在被追踪(看到的是t状态)
	"Z (zombie)",		/* 16 */     // 僵尸状态
	"X (dead)"		    /* 32 */     // 死亡状态
};

接下来我们来看一些进程状态的例子:

  • 运行状态:

image-20231031235917100

image-20231031235745673

  • 休眠状态

image-20231101000050282

image-20231101000033126

这里出现休眠状态的原因是:调用printf的时候需要访问外设——显示器,由于外设的速度很慢(相对于CPU而言),所以大部分时间都是在等在显示器资源,所以我们能看到的状态大多都是休眠。当然如果非常巧合的话,也是能看到R状态的

  • 暂停状态

image-20231101004334337
在这里插入图片描述

这里扩展一下:S是浅度睡眠,可以被终止;D是深度睡眠,无法被OS杀掉,只能通过断电、自己醒来进行解决。出现的原因一般是由于高IO导致的。

  • t状态

image-20231101005813173

image-20231101010109141

tracing stop表示该进程正在被追踪


本节完

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++标准模板(STL)- 类型支持 (复合类型类别,is_member_pointer,is_reference,is_compound)

类型特性 类型特性定义一个编译时基于模板的结构&#xff0c;以查询或修改类型的属性。 试图特化定义于 <type_traits> 头文件的模板导致未定义行为&#xff0c;除了 std::common_type 可依照其所描述特化。 定义于<type_traits>头文件的模板可以用不完整类型实例…

kafka为什么如此之快?

天下武功&#xff0c;唯快不破。同样的&#xff0c;kafka在消息队列领域&#xff0c;也是非常快的&#xff0c;这里的块指的是kafka在单位时间搬运的数据量大小&#xff0c;也就是吞吐量&#xff0c;下图是搬运网上的一个性能测试结果&#xff0c;在同步发送场景下&#xff0c;…

详解:WMS系统IQC来料检验

WMS系统IQC来料检验是仓库管理系统(WMS)中的一个重要环节,它的目的是对进仓原材料进行抽样检验,以确保入库的原材料符合质量标准。WMS系统通过对仓库的收货、存储、配送、装车和信息管理等过程实现集中化、规范化、标准化、自动化的管理。IQC即进货质量抽查。 IQC来料检验的目的…

Mybatis学习

一、 1.第一个mybatis程序 层层递进&#xff0c;SqlSession用来执行sql语句&#xff0c;SqlSession是与数据库的一次会话。 通过SqlSessionFactory获取SqlSession 通过SqlSessionBuilder的build()方法获取SessionFactory 2.第一个程序就找了30分钟的错&#xff08;悲惨&…

【Redis】redis的过期策略如何实现有关定时器的补充

文章目录 redis的过期策略如何实现关于定时器的补充基于优先级队列/堆实现的定时器基于时间轮实现的定时器 redis的过期策略如何实现 注意&#xff1a;不能直接遍历所有的key来判断当前key是否过期&#xff0c;这样子效率非常低&#xff0c;redis整体策略是&#xff1a;定期删…

Java中String的split函数的详解及应用

文章目录 一、 split函数详解二、应用 一、 split函数详解 split(String regex)为java.lang.String类的方法&#xff0c;其功能通俗的说就是以传入的分隔符参数拆分该字符串 方法具体为&#xff1a; public String[] split(String regex) {return split(regex, 0); }方法内部…

4.2 SSAO算法 屏幕空间环境光遮蔽

一、SSAO介绍 AO 环境光遮蔽&#xff0c;全程Ambient Occlustion&#xff0c;是计算机图形学中的一种着色和渲染技术&#xff0c;模拟光线到达物体能力的粗略的全局方法&#xff0c;描述光线到达物体表面的能力。 SSAO 屏幕空间环境光遮蔽&#xff0c;全程 Screen Space Amb…

MySQL与MongoDB,该如何做技术选型?

hello&#xff0c;大家好&#xff0c;我是张张&#xff0c;「架构精进之路」公号作者。 引言 一般情况下&#xff0c;会考虑到MySQL与MongoDB如何做技术选型的时候&#xff0c;你一定是遇到了类似于非结构化数据JSON的存取难题&#xff0c;否则大家都直接MySQL开始搞起了。 为什…

matlab simulink PMSM_SVPWM PI转速控制

1、内容简介 略 8-可以交流、咨询、答疑 2、内容说明 略PMSM_SVPWM PI转速控制 PMSM SVPWM PI转速控制 3、仿真分析 4、参考论文 略

电脑办公最佳拍档 夸克网盘升级低耗能备份、PDF阅读器等功能

临近年终&#xff0c;上班族不仅要总结过去一年的成绩还要开始制定新规划&#xff0c;在这个过程中整理资料是必不可少的环节。对于经常需要使用文件备份和PDF的用户&#xff0c;推荐大家试一下夸克网盘电脑端&#xff0c;升级后的“低耗能备份”和“PDF阅读器”让备份体验更丝…

面试150题做题记录

面试150题做题记录 题目1: 合并两个有序数组 题目1: 合并两个有序数组 题目&#xff1a;https://leetcode.cn/problems/merge-sorted-array/?envTypestudy-plan-v2&envIdtop-interview-150 最优思路&#xff1a;利用原有数列的单调性质&#xff0c;从右往左遍历&#xff…

MySQL启动后反复重新启动故障

MySQL版本为5.6.45 系统为Ubuntu 20.04 LTS 该服务器重启后&#xff0c;MySQL需要手动执行启动。 运行执行脚本后发现异常&#xff0c;如下图&#xff1a; 提示MySQL服务在不停重复启动。 反复使用ps -ef |grep mysql命令查看&#xff0c;发现mysql进程号一直在变化&#x…

Spring Boot Web MVC

文章目录 一、Spring Boot Web MVC 概念二、状态码三、其他注解四、响应操作 一、Spring Boot Web MVC 概念 Spring Web MVC 是⼀个 Web 框架&#xff0c;一开始就包含在Spring 框架里。 1. MVC 定义 软件⼯程中的⼀种软件架构设计模式&#xff0c;它把软件系统分为模型、视…

redis的分布式锁

分布式锁是一种用在分布式系统中实现同步和互斥访问的机制。 1、分布式锁概念 满足分布式系统或者集群模式下&#xff0c;多进程可见并且互斥的锁。 分布式锁的核心思想就是让分布式集群中的节点都适用同一把锁&#xff0c;只要大家使用的是同一把锁&#xff0c;就能锁住线程…

038-第三代软件开发-简易视频播放器-自定义Slider (二)

第三代软件开发-简易视频播放器-自定义Slider (二) 文章目录 第三代软件开发-简易视频播放器-自定义Slider (二)项目介绍简易视频播放器自定义Slider (二)横向纵向 关键字&#xff1a; Qt、 Qml、 关键字3、 关键字4、 关键字5 项目介绍 欢迎来到我们的 QML & C 项目&…

我在Vscode学OpenCV 初步接触

OpenCV是一个开源的计算机视觉库&#xff0c;可以处理图像和视频数据。它包含了超过2500个优化过的算法&#xff0c;用于对图像和视频进行处理&#xff0c;包括目标识别、面部识别、运动跟踪、立体视觉等。OpenCV支持多种编程语言&#xff0c;包括C、Python、Java等&#xff0c…

golang 实现雪花算法

雪花算法概述 snowflake 是 twitter 开源的分布式ID生成算法&#xff0c;其核心思想为&#xff0c;一个long型的ID&#xff1a; 41 bit 作为毫秒数 - 41位的长度可以使用69年10 bit 作为机器编号 &#xff08;5个bit是数据中心&#xff0c;5个bit的机器ID&#xff09; - 10位…

【网络知识必知必会】聊聊网络层IP协议

文章目录 前言IP 协议格式总结 前言 在之前的博文中, 我们聊过了传输层中的两个重点协议 TCP 和 UDP, 本文我们再来聊聊网络层中的一个协议IP, 简单认识一下 IP 协议格式. IP 协议与 TCP 协议的复杂度也不妨多让, 不过我们在这里只是简单的聊一聊 IP 协议的报文格式就行, 毕竟…

图书馆书目推荐数据分析与可视化

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

【Java初阶练习题】-- 循环练习题

循环练习题 1. 根据年龄, 来打印出当前年龄的人是少年(低于18), 青年(19-28), 中年(29-55), 老年(56以上)2. 判定一个数字是否是素数3. 打印 1 - 100 之间所有的素数4. 输出 1000 - 2000 之间所有的闰年5. 输出乘法口诀表6. 求两个正整数的最大公约数7. 求出0&#xff5e;999之…