当前位置: 首页 > news >正文

【Linux】进程查看|fork函数|进程状态

🦄 个人主页——🎐开着拖拉机回家_Linux,大数据运维-CSDN博客 🎐✨🍁

🪁🍁🪁🍁🪁🍁🪁🍁 🪁🍁🪁🍁🪁🍁🪁 🪁🍁🪁🍁🪁🍁🪁🍁🪁🍁🪁🍁

感谢点赞和关注 ,每天进步一点点!加油!

目录

一、基本概念

1.1 概念提出

1.2 特征

二、描述进程-PCB

2.1 什么是进程控制块PCB

2.2 task_struct内容分类(成员)

2.3 进程控制块如何对进程进行管理的呢?

三、查看进程

3.1 通过系统目录查看

3.2 通过用户级工具ps查看

四、通过系统调用获取进程标识符(PID)

4.1 使用getpid和getppid

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

5.1 fork函数

5.2 fork函数创建子进程

六、Linux进程状态

七、两种特殊进程

7.1 僵尸进程

7.2 孤儿进程


一、基本概念


1.1 概念提出


进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体(百度百科)。

1.2 特征


  • 动态性进程的实质是程序在多道程序系统中的一次执行过程,进程是动态产生,动态消亡的。
  • 并发性:任何进程都可以同其他进程一起并发执行
  • 独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位;
  • 异步性由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进
  • 结构特征:进程由程序、数据和进程控制块三部分组成。

多个不同的进程可以包含相同的程序:一个程序在不同的数据集里就构成不同的进程,能得到不同的结果;但是执行过程中,程序不能发生改变。


二、描述进程-PCB


引入一个新概念: 进程控制块PCB(process control block)。PCB就是进程属性的集合(数据结构),里面存储的是进程信息。

2.1 什么是进程控制块PCB


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

即task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含进程的信息。

2.2 task_struct内容分类(成员)


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

2.3 进程控制块如何对进程进行管理


  • 磁盘中的可执行程序在将要运行时,所有的进程中的数据(并不是程序本身)加载到内存中,此时操作系统会建立起一个PCB来保存每一个程序的信息;
  • 这个时候PCB就会对每一个进程都建立起相应的结构体(即进程控制块)将对应的进程的属性、代码等匹配的传到这个结构体中:(这就是先描述)
  • 此时,操作系统就会将每一个进程控制块都连接起来,形成链表结构,并返回头结点。这样便通过数据结构的形式将进程的信息组织起来。

三、查看进程


3.1 通过系统目录查看


根目录下的proc目录,/proc下存储着进程信息。


目录名为数字的即为进程信息的目录,每个目录内存储着他们对应的进程信息。而这些数字对应着该进程的标识符PID。如下查看标识符PID=18964的进程信息:

我们进入进程 18964进程目录

3.2 通过用户级工具ps查看


实例:ps ajx/ps aux

该命令可以查看所有系统进程。如下查看PID=18964的进程信息

创建如下测试脚本并执行

#!/bin/bashproc_test()
{while(true)doecho "I am a process!"sleep 1done
}proc_test## 执行
sh proc_test_18964.sh

另外通过指令对进程进行检测,检测它是否运行:

ps ajx | head -1 && ps ajx | grep  proc_test  | grep -v grep

这里grep实际也是进程,且该进程内包含有proc_test的信息,所以也显示出来了。-v选项是反向搜索的意思,即过滤掉包含有grep内容的信息。

  • PPID (Parent Process ID):代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
  • PID (Process ID): 代表这个进程的代号
  • PGID(Process Group):PGID就是进程所属的Group的Leader的PID,如果PGID=PID,那么该进程是Group Leader
  • SID(Session ID):和PGID非常相似,SID就是进程所属的Session Leader的PID,如果SID==PID,那么该进程是session leader
  • TPGID:终端进程组ID
  • STAT:进程状态

四、通过系统调用获取进程标识符(PID)


4.1 使用getpid和getppid


#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{pid_t id = getpid();while (1){printf("I am a process!pid:%d\n", id);sleep(1);}return 0;
}

执行上面可执行程序并运行如下命令进行监控

while :; do   ps ajx | head -1 && ps ajx | grep  proc_test  | grep -v grep ; sleep 1;done

函数getppid(获取父进程的进程标识符),一般在Linux中普通进程都有他的父进程。

每一个子进程都是由父进程创建出来的。

子进程只能有一个父进程,父进程可以有多个子进程。每次执行可执行程序,进程标识符会改变,因为每次都会创建新的进程。

编写如下测试代码

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{pid_t id = getpid();pid_t fid = getppid();while (1){printf("I am a process!pid:%d ppid:%d\n", id, fid);sleep(1);}return 0;
}

 执行结果如下图:

 多次执行我们发现程序多次执行子进程每次都会创建新的新的进程标识符,父进程标识符没有改变。如下父进程是bash命令行解释器。


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


5.1 fork函数


pid_t  fork(void);

 一个进程包括代码、数据和分配给进程的资源。fork 函数会新生成一个进程,调用 fork 函数的进程为父进程,新生成的进程为子进程。在父进程中返回子进程的 pid,在子进程中返回 0,失败返回-1。

5.2 fork函数创建子进程


创建测试代码: 

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>int main()
{pid_t pid;printf("before fork : pid is : %d, ppid is : %d\n", getpid(), getppid());pid=fork();printf("after fork : pid is : %d, ppid is : %d, fork return %d\n", getpid(), getppid(),pid);sleep(2);return 0;
}

编译后执行

fork函数执行后,后面的"after fork"执行了两次,8897作为父进程创建了子进程 8898。也就是说fork之后,代码共享,从一个进程分为两个分支,一为父,一为子。

进程调用fork,当控制转移到内核中的fork代码后,内核会:

  • 分配新的内存块和内核数据结构给子进程;
  • 将父进程部分数据结构内容拷贝至子进程;
  • 添加子进程到系统进程列表当中;
  • fork返回,开始调度器调度;

所以,fork之前父进程独立执行,fork之后父子两个执行流分别执行。注意:fork之后谁先执行完全由调度器决定。

fork它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:

(1) 在父进程中,fork返回新创建子进程的进程ID;

(2)在子进程中,fork返回0;

(3)如果出现错误,fork返回一个负值;

一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。


六、Linux进程状态


进程状态:

TASK_RUNNING:就绪/可运行状态

TASK_INTERRUPTABLE:进程被挂起(睡眠),直到等待条件为真被唤醒

TASK_UNINTERRUPTABLE:深度睡眠,睡眠期间不响应信号

TASK_STOPPED:进程的执行被暂停

TASK_TRACED:被其它进程跟踪,常用于调试

EXIT_ZOMBIE:僵死状态,进程的执行被终止

EXIT_DEAD:僵死撤销状态,防止wait类系统调用的竞争状态发送

可以使用man ps 查看进程状态 Ss、Sl、S+、Z、I 释义

具体解释如下:

  • D (TASK_UNINTERRUPTIBLE) 不可中断的睡眠状态
  • R (TASK_RUNNING) 正在运行,或在队列中的进程
  • S (TASK_INTERRUPTIBLE)     可中断的睡眠状态
  • T (TASK_STOPPED)    停止状态
  • t (TASK_TRACED) 被跟踪状态
  • Z (TASK_DEAD - EXIT_ZOMBIE) 退出状态,但没被父进程收尸,成为僵尸状态
  • W            进入内存交换(从内核2.6开始无效)
  • X (TASK_DEAD - EXIT_DEAD)   退出状态,进程即将被销毁
  • <    高优先级
  • N    低优先级
  • L    有些页被锁进内存
  • s    包含子进程
  • 位于前台的进程组;
  • l   多线程,克隆线程  multi-threaded (using CLONE_THREAD, like NPTL pthreads do)

七、两种特殊进程


7.1 僵尸进程


1.僵死状态(Zombies)是一个比较特殊的状态。当子进程退出并且父进程(使用wait()系统调用)没有读取到子进程退出的返回代码时就会产生僵死(尸)进程

2.僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。

3.所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态

测试代码 :


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{pid_t id = fork();if (id < 0) {perror("fork");return 1;}else if (id > 0) { //parentwhile(1){printf("parent[%d] is sleeping...,ppid: %d\n", getpid(),getppid());sleep(1);}}else {printf("child[%d] is begin Z...,ppid: %d\n", getpid(),getppid());sleep(5);exit(1);}return 0;
}

fork函数执行后子进程PID:15156 在5 s后exit(1)异常退出 ,父进程15155没有读取到正常的退出代码导致产生僵尸进程。

进程PID:15156的名称加上了【】且后面跟着< defunct > (失效的)

7.2 孤儿进程


修改代码,让子进程和父进程同时不间断运行

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{pid_t id = fork();if (id < 0) {perror("fork");return 1;}else if (id > 0) { //parentwhile(1){printf("parent[%d] is sleeping...,ppid: %d\n", getpid(),getppid());sleep(1);}}else {while(1){printf("child[%d] is begin Z...,ppid: %d\n", getpid(),getppid());sleep(1);}}return 0;
}

运行

while :; do ps ajx | head -1 && ps ajx | grep pro_test | grep -v grep ; sleep 1;done

监控进程状态

杀掉父进程(10552),子进程被编号为1的进程接管,该1号进程就是bash,而bash就是父进程的父进程,父进程被杀死后,bash进程就接管了子进程,这种失去“爸爸”后被接管的进程就被称为孤儿进程。且子进程从前台进程变成了后台进程。


原文链接:fork函数详解-CSDN博客

【Linux】进程周边001之进程概念-CSDN博客

fork()函数详解_fork函数-CSDN博客

原文链接:Linux进程状态_task_interrupt-CSDN博客

 

相关文章:

【Linux】进程查看|fork函数|进程状态

&#x1f984; 个人主页——&#x1f390;开着拖拉机回家_Linux,大数据运维-CSDN博客 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341; &#x1fa81;&#x1f341;&#x1fa81;&am…...

LeetCode第98题 - 有效的括号

题目 解答 方案一 class Solution {public boolean isValidBST(TreeNode root) {if (root null) {return true;}if (root.left null && root.right null) {return true;}if (root.left ! null && root.left.val > root.val) {return false;}if (root.…...

Nacos学习思维导图

一、服务注册 参考文档&#xff1a;http://www.bryh.cn/a/118936.html https://blog.csdn.net/Saintmm/article/details/121981184 二、服务续约 参考文档&#xff1a;http://www.bryh.cn/a/118936.html https://blog.csdn.net/Saintmm/article/details/121981184 三、服务…...

新视野英语课本复盘1

the triumpth of years of hard work 多年的辛勤付出的胜利 get by on very little sleep 靠很少的睡眠勉强维持生活或工作 pursue new passions 追求新的热爱之事 reap the benefits of this opportunity 收获这个机会带来的益处 you will not only emerge as a more broadly …...

Sentinel整合OpenFeign

1、配置文件 feign:sentinel:enabled: true 2、 编写一个工厂类 import com.cart.cartservice.client.ItemClient; import com.cart.cartservice.entity.Item; import lombok.extern.slf4j.Slf4j; import org.springframework.cloud.openfeign.FallbackFactory; import org.sp…...

PyTorch实战:基于Seq2seq模型处理机器翻译任务(模型预测)

文章目录 引言数据预处理加载字典对象en2id和zh2id文本分词 加载训练好的Seq2Seq模型模型预测完整代码结束语 引言 随着全球化的深入&#xff0c;翻译需求日益增长。传统的人工翻译方式虽然质量高&#xff0c;但效率低&#xff0c;成本高。机器翻译的出现&#xff0c;为解决这…...

stm32学习总结:5、Proteus8+STM32CubeMX+MDK仿真串口并使用串口打印日志(注意重定向printf到串口打印的问题)

stm32学习总结&#xff1a;5、Proteus8STM32CubeMXMDK仿真串口并使用串口打印日志&#xff08;注意重定向printf到串口打印的问题&#xff09; 文章目录 stm32学习总结&#xff1a;5、Proteus8STM32CubeMXMDK仿真串口并使用串口打印日志&#xff08;注意重定向printf到串口打印…...

SAFe大规模敏捷企业级实训

课程简介 SAFe – Scaled Agile Framework是目前全球运用最广泛的大规模敏捷框架&#xff0c;也是成长最快、最被认可、最有价值的规模化敏捷框架&#xff0c;目前全球SAFe认证专业人士已达80万人&#xff0c;福布斯100强的70%都在实施SAFe。本课程是一个2天的 SAFe权威培训课…...

中医电子处方系统,西医个体诊所门诊卫生室病历记录查询软件教程

中医电子处方系统&#xff0c;西医个体诊所门诊卫生室病历记录查询软件教程 一、软件程序问答 1、电子处方软件如何快速开单&#xff1f; 如下图&#xff0c;软件以 佳易王诊所电子处方管理系统V17.1版本为例说明 在开电子处方的时候可以按单个药品开&#xff0c;也可以直…...

搞定ESD(八):静电放电之原理图设计

文章目录 一、防护对象识别方法1.1 根据应用手册识别防护对象1.2 根据端口信号类型识别防护对象1.3 根据信号类型识别防护对象二、电路级ESD防护设计2.1 静电尖峰脉冲电压钳位设计(ESD器件并联)2.1.1 高速差分信号ESD防护设计2.1.2 低速信号ESD防护设计2.2 静电放电电流限制设…...

微前端 Micro App

MicroApp 官网链接 MicroApp 链接...

Java amr格式转mp3格式

1.问题描述 微信返回的语音是amr格式的&#xff0c;浏览器不能直接使用&#xff0c;所以需要转为mp3 注意&#xff1a;不能直接使用IO流转为mp3&#xff0c;不然H5还是用不了。转换之后的语音只能在播放器上播放&#xff0c;内里的文件格式其实还是amr 2.使用以下方式转换 音…...

Vue2面试题:说一下虚拟DOM的原理?

虚拟dom是对真实dom的抽象&#xff0c;本质是JS对象 在生成真实DOM之前&#xff0c;vue会把模板编译为一个虚拟dom&#xff0c;当里面某个DOM节点发生变动时&#xff0c;通过diff算法对比新旧虚拟DOM&#xff0c;发现不一样的地方直接修改在真实的DOM上 优点&#xff1a; 可以…...

Spring对bean的管理

一.bean的实例化 1.spring通过反射调用类的无参构造方法 在pom.xml文件中导入坐标&#xff1a; <dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.29<…...

Character Controller Smooth

流畅的角色控制器 Unity的FPS解决方案&#xff01; 它是一种具有非常平滑运动和多种设置的解决方案&#xff1a; - 移动和跳跃 - 坐的能力 - 侧翻角度 - 不平整表面的处理 - 惯性守恒 - 重力 - 与物理物体的碰撞。 - 支持没有家长控制的平台 此解决方案适用于那些需要角色控制器…...

企业内训系统源码开发实战:搭建实践与经验分享

本篇文章中&#xff0c;小编将带领读者深入探讨企业内训系统的源码开发实战&#xff0c;分享在搭建过程中遇到的挑战与解决方案。 一、项目规划与需求分析 通过对企业内训需求的深入了解&#xff0c;我们可以更好地定义系统架构和数据库设计。 二、技术栈选择 在内训系统开发…...

15.三数之和(双指针,C解答附详细分析)

题目描述&#xff1a; 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含…...

SpringCloud微服务 【实用篇】| Dockerfile自定义镜像、DockerCompose

目录 一&#xff1a;Dockerfile自定义镜像 1. 镜像结构 2. Dockerfile语法 3. 构建Java项目 二&#xff1a; Docker-Compose 1. 初识DockerCompose 2. 部署微服务集群 前些天突然发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;…...

Vue3+TS+ElementPlus的安装和使用教程【详细讲解】

前言 本文简单的介绍一下vue3框架的搭建和有关vue3技术栈的使用。通过本文学习我们可以自己独立搭建一个简单项目和vue3的实战。 随着前端的日月更新&#xff0c;技术的不断迭代提高&#xff0c;如今新vue项目首选用vue3 typescript vite pinia……模式。以前我们通常使用…...

浅析锂电池保护板(BMS)系统设计思路(四)SOC算法-扩展Kalman滤波算法

BMS开发板 1 SOC估算方法介绍 电池SOC的估算是电池管理系统的核心&#xff0c;自从动力电池出现以来&#xff0c;各种各样的电池SOC估算方法不断出现。随着电池管理系统的逐渐升级&#xff0c;电池SOC估算方法的效率与精度不断提高&#xff0c;下面将介绍常用几种电池SOC估算方…...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...

Golang——6、指针和结构体

指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

C++实现分布式网络通信框架RPC(2)——rpc发布端

有了上篇文章的项目的基本知识的了解&#xff0c;现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...

Vue 3 + WebSocket 实战:公司通知实时推送功能详解

&#x1f4e2; Vue 3 WebSocket 实战&#xff1a;公司通知实时推送功能详解 &#x1f4cc; 收藏 点赞 关注&#xff0c;项目中要用到推送功能时就不怕找不到了&#xff01; 实时通知是企业系统中常见的功能&#xff0c;比如&#xff1a;管理员发布通知后&#xff0c;所有用户…...

解析“道作为序位生成器”的核心原理

解析“道作为序位生成器”的核心原理 以下完整展开道函数的零点调控机制&#xff0c;重点解析"道作为序位生成器"的核心原理与实现框架&#xff1a; 一、道函数的零点调控机制 1. 道作为序位生成器 道在认知坐标系$(x_{\text{物}}, y_{\text{意}}, z_{\text{文}}…...