科技网站首页欣赏/天津seo优化排名

科技网站首页欣赏,天津seo优化排名,企业展厅布展设计公司,老榕树建站软件🌟🌟作者主页:ephemerals__ 🌟🌟所属专栏:Linux 目录 前言 一、什么是进程 二、task_struct的内容 三、Linux下进程基本操作 四、父进程和子进程 1. 用fork函数创建子进程 五、进程状态 1. 三种重…

🌟🌟作者主页:ephemerals__

🌟🌟所属专栏:Linux

目录

前言

一、什么是进程

二、task_struct的内容

三、Linux下进程基本操作

四、父进程和子进程

1. 用fork函数创建子进程

五、进程状态

1. 三种重要状态

运行状态

阻塞状态

挂起状态

2. 内核链表的理解

3. Linux的进程状态

孤儿进程 

总结


前言

        在学习 Linux 操作系统的过程中,进程是一个至关重要的概念。无论你是想了解系统的基础操作,还是深入研究 Linux 内核,进程管理的理解都将为你打下坚实的基础。进程不仅是操作系统资源管理的核心,也是实现多任务处理的关键所在。通过学习进程的创建、调度、同步等机制,你可以更好地掌握操作系统的运行原理,进而优化系统性能和解决实际问题。本文将从基础知识入手,带领大家逐步深入探索 Linux 中进程的各个方面,帮助你在 Linux 学习的道路上迈出坚实的第一步。

一、什么是进程

         进程有多种描述方式,例如:程序的运行实例、正在执行的程序、操作系统进行资源调配的基本单位等。不过,以上说法都太理论化,我们用程序运行的实际情况来描述进程。

        一个程序在执行前,其二进制代码和数据(变量、常量、堆栈数据等)需要加载到内存。当加载完成之后,操作系统就会为这一块代码和数据创建一个对应的PCB(也叫做进程控制块,本质是一个存储进程相关信息的结构体),其中存在一个内存指针,指向代码和数据,便于访问。

        所以“进程”不仅仅包括了程序的运行实例,它也包括操作系统管理该进程的相关信息。简而言之,“进程”是指PCB与程序代码数据的集合操作系统根据PCB来跟踪进程的执行状态,方便对进程进行调度。

        而当有多个程序需要执行时,操作系统就会为每一个程序的代码和数据都创建一个对应的PCB(描述过程),再通过容器将所有的PCB串联起来(组织过程)。此时,操作系统对于进程的管理即为对容器的增删查改

需要注意:

在Linux下,PCB(进程控制块)是一个叫做task_struct的结构体;进程的所有属性都可以通过task_struct直接或间接地找到。

Linux下的task_struct之间通过双向链表进行连接。

二、task_struct的内容

 task_struct有如下成员,用于表示进程各种状态信息,以及访问程序的代码和数据:

  • 进程标识符(PID)--区别其他进程

  • 进程状态信息

  • 优先级

  • 程序计数器

  • 内存指针--指向代码和数据

  • 上下文数据

  • I/O状态信息

  • 记账信息

  • 其他信息

 之后的进程学习当中,我们将围绕以上成员数据,学习进程的相关概念及操作

三、Linux下进程基本操作


C语言函数获取当前进程标识符和父进程的标识符(PID):

getpid(); //返回当前进程标识符,返回值类型是pid_t
getppid(); //返回当前进程的父进程标识符

注意使用以上函数时,需要引头文件<unistd.h>


使用指令查看当前所有进程:

ps ajx
ls /proc

根据程序名查看某个进程信息:

ps ajx | head -1 && ps ajx | grep (可执行程序名)

根据标识符查看进程文件:

ll /proc/(标识符)

示例:

我们可以重点关注一下图中列举出的两个文件cwdexe

cwd指的是当前进程对应的可执行程序所在目录;

exe指的是当前进程对应的可执行程序位置。


C语言函数修改当前进程所在路径:

chdir("(路径)");

注意使用该函数要引头文件<unistd.h>


杀进程的两种方式:

1. ctrl + c

2. 命令行输入kill -9  (进程标识符)

四、父进程和子进程

        一个进程通过系统调用创建出的另一个进程称之为该进程的子进程,反之该进程称为其父进程。在Linux下,我们在命令行输入的命令都是Bash(命令行解释器)的子进程。

1. 用fork函数创建子进程

         fork是一个系统调用,存在于头文件<unistd.h>中,当执行fork函数之后,当前进程会创建一个子进程,后续的代码会被父进程和子进程分别执行一次

代码示例:

#include <stdio.h>
#include <unistd.h>int main()
{fork();printf("hello world\n");return 0;
}

运行结果:

注意:fork函数创建的子进程没有自己的代码和数据,虽然操作系统为其创建了PCB,但是其内存指针指向的还是父进程的代码和数据。

 子进程在创建成功后,fork函数会给子进程返回0,给父进程返回子进程的PID。为什么会给父子进程不同的返回值呢?因为一个父进程可能会有多个子进程,给父进程返回子进程的PID,更方便父进程对子进程进行管理。而子进程如果想要知道父进程的PID,直接调用getppidh函数即可。另外,返回值不同可以配合分支语句让父子进程执行不同的代码。示例如下:

#include <stdio.h>
#include <unistd.h>int main()
{pid_t id = fork();if(id == 0)//子进程{printf("我是子进程,我的pid是%d\n", getpid());}else//父进程{printf("我是父进程,我的pid是%d\n", getpid());}return 0;
}

运行结果:

        那么,为什么fork函数能够做到返回两个值呢?实际上fork函数在执行return语句之前,就已经创建好了子进程,此时就可以通过分支语句来区分给父进程和子进程的返回值。 

注意:虽然fork函数创建的子进程与父进程的代码是共享的,但如果父子任何一方要修改其中的数据,那么操作系统就会将数据进行拷贝,此时父子就各自维护自己的数据,本质上修改的是拷贝的数据,不会影响另一方。这种状况叫做写时拷贝

五、进程状态

        对于不同的操作系统,进程状态可能略有不同,但常见的大体上的进程状态有如下几种:创建、就绪、运行、阻塞、终止、挂起。我们介绍一下其中最重要的三点:运行状态、阻塞状态和挂起状态

1. 三种重要状态

运行状态

        首先要知道,一般情况下一个CPU维护一个进程调度队列,该队列中存放着一个个PCB,等待CPU对它们进行调度。而一个PCB在运行队列中排队时,就称该进程处于运行状态

阻塞状态

        当一个进程需要等待某种资源或设备(如鼠标、键盘等)就绪时,该进程就处于阻塞状态。阻塞状态的进程在代码层面的体现是:PCB从运行队列中移出,转而进入设备的等待队列当中

此时若设备准备就绪(如按下键盘),则操作系统会修改当前设备状态,然后检查等待队列,将等待队列中的PCB重新移动到运行队列当中,该进程重新恢复运行状态。

挂起状态

        当一个进程被暂停执行时,称该进程处于挂起状态。 那么它的具体体现是什么呢?

        当内存空间较为吃紧时,操作系统会将一些暂时不需要使用的内存数据(如阻塞状态的PCB控制的代码和数据唤出到磁盘中的swap交换分区。此时等待队列中的PCB不再维护该进程的代码和数据,这样的进程状态叫做阻塞挂起

        此时,若设备准备就绪,则操作系统就将swap交换分区中的代码和数据重新唤入到内存中,给PCB维护,然后恢复到运行状态。

        当内存空间严重不足时,操作系统会将运行状态的PCB控制的代码和数据也唤出到swap交换分区。此时称之为运行挂起


由这三种状态在代码层面的一部分具体体现,我们可以得出如下结论:进程状态的变化表现之一就是PCB在不同的数据结构之间移动,变化本质是操作系统对数据结构的增删查改

2. 内核链表的理解

        之前提到,在Linux下,操作系统会使用双向链表将PCB串联起来,方便进程管理。那么为什么PCB还会出现在CPU维护的调度队列当中呢?其实task_struct确实是同时出现在两种数据结构当中的,它基于一种特殊的结构来实现: 

task_struct当中,将用于构成双向链表的指针域封装成一个结构体list_head,它的指针指向的是其他task_struct的list_head。那么既然指向另一个指针域,如何能访问到task_struct的其他成员呢?这就需要用到结构体内存对齐的相关知识了:结构体的成员都是按照自身的对齐数进行存储的,第一个成员变量的地址就是结构体的首地址。通过求出list_head相对于结构体第一个成员的偏移量,就能间接访问结构体的其他成员。例如,如下表达式就可以表示next指针指向的list_head所在task_struct的首地址(其中links表示list_head的变量):

(struct task_struct*)(next - &((struct task_struct*)0->links))

将0强转为task_struct*类型,求出成员links的地址,即为links的偏移量,然后用links的地址减去该偏移量,得出task_struct的首地址,再强转为task_struct*类型,然后就可以访问其他成员了。

        而其他指针域也可以通过这种方式访问task_struct的其余成员,但可以用不同的链接方式,形成不同的数据结构,这样就实现了一个PCB同时存在于多种数据结构的壮举。

3. Linux的进程状态

        相比于之前提到的操作系统大体上的进程状态,Linux的进程状态就显得更加具体化。在Linux下,进程状态本质是task_struct内的长整型变量,它有以下几种进程状态表示:

static const char *const task_state_array[] = {"R (running)", /*0 */"S (sleeping)", /*1 */"D (disk sleep)", /*2 */"T (stopped)", /*4 */"t (tracing stop)", /*8 */"X (dead)", /*16 */"Z (zombie)", /*32 */
};

R:运行状态

S:休眠状态(可中断休眠)

D:深度睡眠状态(不可中断休眠)

进程处于深度睡眠状态时,不可被杀。

T:暂停状态--用户手动暂停进程(如Ctrl + z)

t:追踪状态--调试过程中执行到断点处,进程被暂停

x:死亡状态

z:僵尸状态--子进程在死亡之后,代码和数据可以释放,但其PCB不能直接释放,需要被父进程读取信息,读取信息之前称之为僵尸状态。

注意:如果父进程一直都不读取子进程的信息,那么僵尸状态就会一直存在,PCB也会一直存在,这就导致了内存泄漏。

孤儿进程 

        除了以上几种状态,进程还有一种特殊情况:孤儿进程。 当父进程先死亡,子进程就会被1号进程领养,成为新的父进程,此时该子进程就被称作孤儿进程。

注:1 号进程(init 或 systemd) 是 Linux 系统中的第一个用户态进程,负责初始化系统并管理其他进程。它由内核在系统启动时创建,PID固定为 1。现代 Linux 主要使用 systemd 作为 1 号进程,提供服务管理、日志收集和系统控制功能,而早期系统则使用 sysvinit 或 upstart。如果 1 号进程崩溃,系统通常会进入不可用状态,需要重启。

        那么为什么子进程会被1号进程领养呢?如果1号进程不领养它,则当子进程死亡后,没有父进程读取信息,就会造成内存泄漏

总结

        通过本篇文章,我们学习了Linux进程的基础知识,包括进程概念、task_struct 结构、进程状态以及父子进程关系,希望这篇文章能帮助你更清晰地理解Linux进程的运行机制。如果你觉得博主讲的还不错,就请留下一个小小的赞在走哦,感谢大家的支持❤❤❤

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

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

相关文章

odbus TCP转Modbus RTU网关快速配置案例

Modbus TCP 转Modbus RTU网关快速配置案例 在工业自动化领域&#xff0c;Modbus 协议以其简洁和高效而著称&#xff0c;成为众多设备通信的首选。 随着技术的发展和应用场景的变化&#xff0c;Modbus 协议也发展出了不同的版本&#xff0c;其中 Modbus TCP 和 Modbus RTU 是两种…

《高效迁移学习:Keras与EfficientNet花卉分类项目全解析》

从零到精通的迁移学习实战指南&#xff1a;以Keras和EfficientNet为例 一、为什么我们需要迁移学习&#xff1f; 1.1 人类的学习智慧 想象一下&#xff1a;如果一个已经会弹钢琴的人学习吉他&#xff0c;会比完全不懂音乐的人快得多。因为TA已经掌握了乐理知识、节奏感和手指…

Android 手机启动过程

梳理 为了梳理思路&#xff0c;笔者画了一幅关于 Android 手机启动的过程图片内容纯属个人见解&#xff0c;如有错误&#xff0c;欢迎各位指正

【Linux】:封装线程

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家带来封装线程相关的知识点&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精通 数据结…

星越L_三角指示牌及危险警示灯使用

目录 1.打开危险警告灯 2.取出反光背心穿上 3.取出指示牌 4.放置三角指示牌。 1.打开危险警示灯 2.取出反光背心穿上 3.取出指示牌

AI与人的智能,改变一生的思维模型【7】易得性偏差

目录 **易得性偏差思维模型&#xff1a;大脑的「热搜算法」与反操纵指南****病毒式定义&#xff1a;你的大脑正在被「热搜」劫持****四大核心攻击路径与史诗级案例****1. 信息过载时代的「认知短路」****2. 媒体放大器的「恐怖滤镜」****3. 个人经验的「数据暴政」****4. 社交茧…

Jmeter的简单使用

前置工作 确保java8 版本以上jmeter下载路径&#xff08;选择Binaries&#xff09;&#xff1a;https://jmeter.apache.org/download_jmeter.cgi直接解压&#xff0c;找到bin下面的文件&#xff1a;jmeter.bat&#xff08;可选&#xff09;汉化&#xff0c;修改 jmeter.proper…

MyBatis源码分析の配置文件解析

文章目录 前言一、SqlSessionFactoryBuilder1.1、XMLConfigBuilder1.2、parse 二、mappers标签的解析2.1、cacheElement2.1.1、缓存策略 2.2、buildStatementFromContext2.2.1、sql的解析 前言 本篇主要介绍MyBatis源码中的配置文件解析部分。MyBatis是对于传统JDBC的封装&…

golang快速上手基础语法

变量 第一种&#xff0c;指定变量类型&#xff0c;声明后若不赋值&#xff0c;使用默认值0 package mainimport "fmt"func main() {var a int //第一种&#xff0c;指定变量类型&#xff0c;声明后若不赋值&#xff0c;使用默认值0。fmt.Printf(" a %d\n"…

工程实践:如何使用SU17无人机来实现室内巡检任务

阿木实验室最近发布了科研开发者版本的无人机SU17&#xff0c;该无人机上集成了四目视觉&#xff0c;三维激光雷达&#xff0c;云台吊舱&#xff0c;高算力的机载计算机&#xff0c;是一个非常合适的平台用于室内外巡检场景。同时阿木实验室维护了多个和无人机相关的开源项目。…

蓝桥杯嵌入式赛道复习笔记1(led点亮)

前言 基础的文件创建&#xff0c;参赛资源代码的导入&#xff0c;我就不说了&#xff0c;直接说CubeMX的配置以及代码逻辑思路的书写&#xff0c;在此我也预祝大家人人拿国奖 理论讲解 原理图简介 1.由于存在PC8引脚到PC15引脚存在冲突&#xff0c;那么官方硬件给的解决方案…

Linux进程1.0--task_struct

1.硬件&#xff1a;冯诺依曼体系结构&#xff1a; 单个分析&#xff1a;、 数据流向&#xff1a;数据必须先进入输入设备&#xff0c;再到存储器&#xff0c;然后由存储器给控制器&#xff0c;控制器收到以后进行相应的处理后&#xff0c;再传回存储器&#xff0c;存储器最终传…

代码随想录day17 二叉树part05

654.最大二叉树 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&#xff0c;其值为 nums 中的最大值。 递归地在最大值 左边 的 子数组前缀上 构建左子树。 递归地在最大值 右边 的 子数组后缀上 构建右子树。 返回 nums …

宇树人形机器人开源模型

1. 下载源码 https://github.com/unitreerobotics/unitree_ros.git2. 启动Gazebo roslaunch h1_description gazebo.launch3. 仿真效果 H1 GO2 B2 Laikago Z1 4. VMware: vmw_ioctl_command error Invalid argument 这个错误通常出现在虚拟机环境中运行需要OpenGL支持的应用…

通过特征值和特征向量实现的图像压缩和特征提取

前文&#xff0c;我们在学习人工智能的线性代数基础的时候&#xff0c;就了解到&#xff0c;矩阵在人工智能中被广泛使用&#xff0c;接下来我们就从大家非常常见的图像开始&#xff0c;深度理解矩阵在人工智能中的应用。有关线性代数基础的文章可以看的我CSDN:人工智能中的线性…

蓝桥杯2023年第十四届省赛真题-整数删除 暴力-->链表+小根堆

题目来自DOTCPP&#xff1a; 思路&#xff1a; ①每次找到数列中的最小值下标&#xff0c;然后用状态数组st标记它&#xff0c;相当与删除它&#xff0c;之后就不会访问它。 ②对最小值下标左边和右边判断一下&#xff0c;看有没有数字&#xff0c;如果有就把最小值加到两边第…

springboot438-基于SpringBoot的数字化教学资源管理系统(源码+数据库+纯前后端分离+部署讲解等)

&#x1f495;&#x1f495;作者&#xff1a; 爱笑学姐 &#x1f495;&#x1f495;个人简介&#xff1a;十年Java&#xff0c;Python美女程序员一枚&#xff0c;精通计算机专业前后端各类框架。 &#x1f495;&#x1f495;各类成品Java毕设 。javaweb&#xff0c;ssm&#xf…

蓝桥杯刷题——第十五届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组

一、0握手问题 - 蓝桥云课 算法代码&#xff1a; #include <iostream> using namespace std; int main() {int sum0;for(int i49;i>7;i--)sumi;cout<<sum<<endl;return 0; } 直接暴力&#xff0c;题意很清晰&#xff0c;累加即可。 二、0小球反弹 - 蓝…

跨境卫士跟vps哪个更好用?跨境卫士为卖家提供固定IP环境

跨境卫士是通过为卖家提供固定的环境 i p来隔离本地电脑环境&#xff0c;为卖家创造一个真实独立的物理环境&#xff0c;让买家再任意电脑&#xff0c;任意网络下都能够安全的管理账号。跨境卫士和紫鸟原理一样&#xff0c;是通过为卖家提供固定的环境 i p来隔离本地电脑环境&a…

coding ability 展开第四幕(滑动指针——巩固篇)超详细!!!!

文章目录 前言水果成篮思路 找到字符串中所有字母异位词思路 串联所有单词的子串思路 最小覆盖子串思路 总结 前言 本专栏上一篇博客&#xff0c;带着大家从认识滑动窗口到慢慢熟悉 相信大家对滑动窗口已经有了大概的认识 其实主要就是抓住——一段连续的区间 今天来学习一些滑…