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

【Linux篇】进程入门指南:操作系统中的第一步

步入进程世界:初学者必懂的操作系统概念

  • 一. 冯诺依曼体系结构
    • 1.1 背景与历史
    • 1.2 组成部分
    • 1.3 意义
  • 二. 进程
    • 2.1 进程概念
      • 2.1.1 PCB(进程控制块)
    • 2.2 查看进程
      • 2.2.1 使用系统文件查看
      • 2.2.2 使⽤top和ps这些⽤⼾级⼯具来获取
      • 2.2.3 通过系统调用获取进程标识符
    • 2.3 创建子进程
    • 2.4 进程状态
      • 2.4.1 查看进程状态
  • 三. 最后

前言

在计算机系统中,进程是执行程序的基本单位。它不仅仅是代码的集合,更是操作系统管理和分配资源的核心对象。每当我们运行一个应用程序,操作系统就会为其创建一个进程,使得程序能够在计算机中独立执行并进行资源管理。理解进程的概念对于深入学习操作系统和高效利用计算机资源至关重要。 接下来的篇章将带领大家深入探讨进程管理。

💬 欢迎讨论:如果你在学习过程中有任何问题或想法,欢迎在评论区留言,我们一起交流学习。你的支持是我继续创作的动力!
👍 点赞、收藏与分享:觉得这篇文章对你有帮助吗?别忘了点赞、收藏并分享给更多的小伙伴哦!你们的支持是我不断进步的动力!
🚀 分享给更多人:如果你觉得这篇文章对你有帮助,欢迎分享给更多对Linux OS感兴趣的朋友,让我们一起进步!

一. 冯诺依曼体系结构

在这里插入图片描述

1.1 背景与历史

冯·诺依曼体系结构是现代计算机的基础设计模型,由约翰·冯·诺依曼于1945年提出。该结构的核心思想是将程序和数据存储在同一个内存中,计算机通过中央处理单元(CPU)按顺序执行指令。再此向大佬致敬。👏

1.2 组成部分

  • CPU(中央处理器)由运算器和控制器组成。

存储器(内存)是CPU进行读、获取的必要手段,CPU执行程序,必须先加载,将代码及数据加载到内存,CPU执行代码,访问数据。

结构由五个基本组成部分构成:输入设备、输出设备、存储器、运算器和控制单元。

1.3 意义

它的意义在于简化了计算机设计,提高了计算机的可编程性,使得不同的程序可以通过修改存储器中的指令和数据来实现多种功能。冯·诺依曼体系结构成为现代计算机系统的标准架构,推动了计算机技术的飞速发展。

二. 进程

2.1 进程概念

进程是程序的一次执行实例,是操作系统进行资源分配和调度的基本单位。它拥有独立的内存空间、系统资源(如文件句柄、网络端口)和运行状态。

本人理解:进程 = 内核数据结构对象 + 代码和数据 (进程 = PCB(进程控制块) + 代码和数据)

2.1.1 PCB(进程控制块)

进程的所有属性全保存在PCB中,Linux操作系统下的PCB为 task_struct, 该结构体为Linux内核中的一种数据结构,它会被加载到内存(RAM)中。

task_struct具有的部分信息,另一部分的信息将在后续的博客讲解

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

OS如何对各种进程进行的管理的?先描述,在组织。
所有运行的进程都以 task_struct 链表的形式存在内核中。
在这里插入图片描述

2.2 查看进程

2.2.1 使用系统文件查看

命令格式:

ls /proc/ [pid]

  • 功能

查看指定进程的进程信息。不加pid则查看所有进程的信息

2.2.2 使⽤top和ps这些⽤⼾级⼯具来获取

命令格式:

  • ps ajx | grep myprocess | grep -v grep

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

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
printf("pid: %d\n", getpid());
printf("ppid: %d\n", getppid());
return 0;
}
  • getpid()系统调用,用于获取当前进程的 PID(Process ID),在子进程中调用 getpid(),返回的是子进程自身的 PID。
  • getppid()系统调用,用于获取当前进程的父进程PID。

2.3 创建子进程

示例代码:

#include<stdio.h>
#include<unistd.h>
#include <sys/types.h>int gval = 100;int main()
{printf("父进程开始运行 ,pid: %d\n",getpid());pid_t id = fork();if(id < 0){perror("id");return 1;}else if(id == 0){printf("我是一个子进程 !, 我的pid:%d, 我的父进程id:%d, gval: %d\n",getpid(),getppid(),gval);sleep(5);//childwhile(1){sleep(1);printf("子进程修改变量 : %d -> %d", gval,  gval+10);gval+=10;printf("我是一个子进程 !, 我的pid:%d, 我的父进程id:%d\n",getpid(),getppid());}}else{//fatherwhile(1){sleep(1);printf("我是一个父进程 !, 我的pid:%d, 我的父进程id:%d, gval: %d\n",getpid(),getppid(),gval);}}printf("进程开始运行 ,pid: %d\n",getpid());return 0;
}

子进程会共享父进程的代码和数据,如果父子任何一方对数据进行修改,OS系统会在底层第数据进行拷贝,让目标进程修改这个拷贝。

问题1:为什么fork给父子返回各自不同的返回值?

  • 父进程中的返回值:

fork() 在父进程中返回 子进程的 PID(进程 ID)。这个 PID 是一个正整数,唯一标识子进程。父进程可以使用该 PID 来跟踪子进程,执行如等待子进程结束、获取子进程的状态等操作。

  • 子进程中的返回值:

在子进程中,fork() 返回 0。子进程通过这个返回值可以判断自己是否是子进程,父进程通过返回值判断是否是父进程。

问题2:为什么一个函数会返回两次?

  • 父进程的情况:

返回值是子进程的 PID(进程ID),是一个正整数。

父进程用这个 PID 来识别和管理子进程。父进程可以使用这个 PID 来执行如 wait()、waitpid() 等系统调用,等待子进程终止或获取子进程的退出状态。

  • 子进程的情况:

返回值是 0。

子进程用返回值 0 来判断自己是子进程,以便执行不同于父进程的代码。子进程可能会通过这个返回值执行某些特定的初始化工作或处理。

结论:fork() 会返回两次是因为它在父进程和子进程中分别执行,父进程获得的是子进程的 PID,子进程获得的是 0。通过这个返回值,父进程和子进程可以执行不同的代码,保证了进程的正确管理和并行执行。

问题3:fork两个返回值各种给⽗⼦如何返回?

  • 父进程:父进程使用返回子进程的PID,来管理或等待子进程。
  • 子进程:子进程返回0,子进程用这个值来判断自己是子进程,以执行不同于父进程代码逻辑(比如初始化、执行任务等)。
  • fork返回负值,表示fork调用失败(资源不足等)它会返回 -1,并且没有子进程创建。操作系统会设置 errno 来表示具体的错误原因。

2.4 进程状态

请看Linux内核关于进程状态的描述:

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 */
};

  1. R(running): 运行状态,表示某进程正在运行或准备运行。
  2. S(sleep): 睡眠状态,进程在等待某些事件完成(也称为浅度睡眠,可中断睡眠)。
  3. D(disk sleep): 磁盘休眠状态,进程通常在等待I/O操作完成(也称为深度睡眠,不可中断睡眠)。
  4. T(stopped): 停止状态,可以通过发送信号让该进程继续进行。
  5. t(Tracing stop): 通常是在进行调试或进程跟踪时出现的状态。
  6. X(dead): 死亡状态,不会出现在进程列表中。
  7. Z(Zombie): 僵尸状态,子进程已结束,父进程为获取子进程的退出信息。

2.4.1 查看进程状态

使用ps aux 或 ps ajx 命令可以查看进程的详细状态。
命令选项含义:

  • a:显⽰⼀个终端所有的进程,包括其他⽤⼾的进程。
  • x:显⽰没有控制终端的进程,例如后台运⾏的守护进程。
  • j:显⽰进程归属的进程组ID、会话ID、⽗进程ID,以及与作业控制相关的信息。
  • u:以⽤⼾为中⼼的格式显⽰进程信息,提供进程的详细信息,如⽤⼾、CPU和内存使⽤情况等。

僵尸进程危害
进程的退出状态必须被维持下去,因为他要告诉关⼼它的进程(⽗进程),你交给我的任务,我办的怎么样了。可⽗进程如果⼀直不读取,那⼦进程就⼀直处于Z状态。
• 维护退出状态本⾝就是要⽤数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,
换句话说,Z状态⼀直不退出,PCB⼀直都要维护?是的!
• 那⼀个⽗进程创建了很多⼦进程,就是不回收,是不是就会造成内存资源的浪费。因为数据结构对象本⾝就要占⽤内存,想想C中定义⼀个结构体变量(对象),是要在内存的某个位置进⾏开辟空间!
• 内存泄漏

孤儿进程

⽗进程如果提前退出,那么⼦进程后退出,进⼊Z之后,那该如何处理呢?
• ⽗进程先退出,⼦进程就称之为“孤⼉进程”
• 孤⼉进程被1号init进程领养,当然要有init进程回收

如何避免孤儿进程

  1. 父进程等待子进程退出(避免子进程成为孤儿进程)

父进程可以通过适当的进程管理确保它会在子进程结束时正确地回收子进程的资源,避免进程成为孤儿进程。常用的技术包括:

wait() 或 waitpid():父进程可以使用 wait() 或 waitpid() 来等待子进程结束,并获取子进程的退出状态,从而清理和回收子进程的资源。这样,即使父进程在结束之前退出,它也能确保子进程的资源得到回收。

  1. 使用 signal() 或 sigaction() 捕获终止信号

如果父进程结束时没有来得及清理子进程的资源,可以通过捕获特定信号(如 SIGCHLD)来及时回收子进程的资源。通过设置 SIGCHLD 信号处理函数,父进程可以在子进程结束时自动清理。

  1. 避免父进程直接退出

父进程应该在子进程完成后再退出,例如通过使用 wait() 等系统调用等待子进程完成后再退出。如果父进程在子进程结束前退出,可能导致子进程变成孤儿进程。

定期检查子进程状态,使用 waitpid() 等方法主动回收子进程的资源。

三. 最后

本文主要介绍了操作系统中的进程管理,包括冯诺依曼体系结构、进程概念、进程控制块(PCB)、进程状态及如何查看和管理进程。
冯诺依曼体系结构是现代计算机设计的基础,它将程序和数据存储在同一内存中,提升了计算机的可编程性。进程则是程序的执行实例,操作系统通过进程控制块(PCB)来管理进程的资源和状态。进程通过 fork() 创建子进程,父子进程通过返回值区分身份。进程有不同的状态,如运行、睡眠、停止等,父进程可以通过 wait() 等系统调用回收子进程资源,避免孤儿进程的产生。如果父进程提前退出,子进程可能成为孤儿进程,操作系统会由 init 进程接管。为了避免孤儿进程,父进程应在子进程结束后再退出,并通过信号捕获机制及时清理资源。

路虽远,行则将至;事虽难,做则必成

亲爱的读者们,下一篇文章再会!! \color{Red}亲 爱 的 读 者 们 , 下 一 篇 文 章 再 会 ! ! 亲爱的读者们,下一篇文章再会!!

相关文章:

【Linux篇】进程入门指南:操作系统中的第一步

步入进程世界&#xff1a;初学者必懂的操作系统概念 一. 冯诺依曼体系结构1.1 背景与历史1.2 组成部分1.3 意义 二. 进程2.1 进程概念2.1.1 PCB&#xff08;进程控制块&#xff09; 2.2 查看进程2.2.1 使用系统文件查看2.2.2 使⽤top和ps这些⽤⼾级⼯具来获取2.2.3 通过系统调用…...

JavaScript 中的原型链与继承

JavaScript 是一种基于原型的编程语言&#xff0c;这意味着它的对象继承是通过原型链而非类的机制来实现的。原型链是 JavaScript 中对象与对象之间继承属性和方法的基础。本文将深入探讨 JavaScript 中的原型链和继承机制&#xff0c;帮助你理解这一重要概念。 一、原型&…...

无线通信技术(二):ITU、3GPP及传统波段对无线频谱的划分

目录 一.ITU波段划分 二.3GPP频带划分&#xff08;仅介绍5G NR&#xff09; 2.1 频带分类 2.2 频带划分表 2.2.1 FR1 2.2.2 FR2 2.3 全球部署趋势 三.传统波段划分 3.1 射频工程中的微波 3.2 军用雷达波段命名 本文介绍国际标准组织ITU、3GPP和传统波段对无线频谱的划…...

Android 系统ContentProvider流程

一、ContentProvider初始化注册流程 源码查看路径&#xff1a;http://xrefandroid.com/android-11.0.0_r48/ 涉及到源码文件&#xff1a; /frameworks/base/core/java/android/content/ContentProvider.java 自定义ContentProvider需要继承该类,内部类Transport继承关系如下,实…...

SpringBean模块(一)定义如何创建生命周期

一、介绍 1、简介 在 Spring 框架中&#xff0c;Bean 是指由 Spring 容器 管理的 Java 对象。Spring 负责创建、配置和管理这些对象&#xff0c;并在应用程序运行时对它们进行依赖注入&#xff08;Dependency Injection&#xff0c;DI&#xff09;。 通俗地讲&#xff0c;Sp…...

k8s存储介绍(六)StorangeClass

一、Kubernetes 存储类&#xff08;StorageClass&#xff09;详解 1. 什么是 StorageClass&#xff1f; 在 Kubernetes 中&#xff0c;StorageClass&#xff08;存储类&#xff09;是一种用于动态创建 PersistentVolume&#xff08;PV&#xff09;的资源对象。它允许管理员根…...

Redis-04.Redis常用命令-字符串常用命令

一.字符串操作命令 set name jack 点击左侧name&#xff0c;显示出值。 get name get abc&#xff1a;null setex key seconds value&#xff1a;设置过期时间&#xff0c;过期后该键值对将会被删除。 然后再get&#xff0c;在过期时间内可以get到&#xff0c;过期get不到。…...

golang接口-interface

interface接口 概述 接口&#xff08;interface&#xff09;是 Go 语言中的一种类型&#xff0c;用于定义行为的集合&#xff0c;它通过描述类型必须实现的方法&#xff0c;规定了类型的行为契约。 它把所有的具有共性的方法定义在一起&#xff0c;任何其他类型只要实现了这…...

Epub转PDF软件Calibre电子书管理软件

Epub转PDF软件&#xff1a;Calibre电子书管理软件 https://download.csdn.net/download/hu5566798/90549599 一款好用的电子书管理软件&#xff0c;可快速导入电脑里的电子书并进行管理&#xff0c;支持多种格式&#xff0c;阅读起来非常方便。同时也有电子书格式转换功能。 …...

【自学笔记】PHP语言基础知识点总览-持续更新

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1. PHP 简介2. PHP 环境搭建3. 基本语法变量与常量数据类型运算符 4. 控制结构条件语句循环语句 5. 函数函数定义与调用作用域 6. 数组7. 字符串8. 表单处理9. 会话…...

FAST-LIVO2 Fast, Direct LiDAR-Inertial-Visual Odometry论文阅读

FAST-LIVO2 Fast, Direct LiDAR-Inertial-Visual Odometry论文阅读 论文下载论文翻译FAST-LIVO2: 快速、直接的LiDAR-惯性-视觉里程计摘要I 引言II 相关工作_直接方法__LiDAR-视觉&#xff08;-惯性&#xff09;SLAM_ III 系统概述IV 具有顺序状态更新的误差状态迭代卡尔曼滤波…...

【Git】--- Git远程操作 标签管理

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; Git 前面我们学习的操作都是在本地仓库进行了&#xff0c;如果团队内多人协作都在本地仓库操作是不行的&#xff0c;此时需要新的解决方案 --- 远程仓库。…...

Docker学习之服务编排(day9)

文章目录 前言一、问题描述二、解决方案1.安装Docker Compose1.1 [github下载相应版本](https://github.com/docker/compose/releases)1.2 将下载的文件移动到 /usr/local/bin 目录&#xff0c;确保它能够被系统识别为可执行文件1.3 赋予执行权限1.4 验证安装1.5 创建软链 2. 使…...

前后端常见模型以及相关环境配置介绍

一、前端常见框架 Vue.js 特点&#xff1a;采用数据驱动的响应式编程&#xff0c;组件化的开发模式使得代码结构清晰&#xff0c;易于维护&#xff0c;且学习成本相对较低&#xff0c;适合初学者和快速迭代的项目。应用场景&#xff1a;广泛应用于各类 Web 应用开发&#xff…...

职能型组织、项目型组织、矩阵型组织的介绍及优缺点比较

PMP考试中&#xff0c;经常会涉及到职能型组织、项目型组织、矩阵型组织的比较&#xff0c;下面简单介绍下职能型组织、项目型组织、矩阵型组织及其优缺点&#xff1a; 一、职能型组织 定义&#xff1a;以专业职能划分部门&#xff08;如财务、技术、市场等&#xff09;&…...

Java基本类型深度解析:从内存模型到高效编程实践

Java基本类型深度解析&#xff1a;从内存模型到高效编程实践 一、Java基本类型概述 Java作为强类型语言&#xff0c;定义了8种基本数据类型&#xff08;Primitive Types&#xff09;&#xff0c;这些类型直接存储数据值而非对象引用&#xff0c;是构建Java程序的基础。它们的…...

论文阅读笔记——ST-4DGS,WideRange4D

ST-4DGS ST-4DGS 论文 在 4DGS 中&#xff0c;变形场 F \mathcal{F} F 与运动参数 X 和形状参数 ( S , R ) (S,R) (S,R) 高度耦合&#xff0c;导致训练时高斯表示紧凑型退化&#xff0c;影响动态渲染质量。由此&#xff0c;本文提出两种方法解耦运动与形状参数&#xff0c;保…...

[python]基于yolov8实现热力图可视化支持图像视频和摄像头检测

YOLOv8 Grad-CAM 可视化工具 本工具基于YOLOv8模型&#xff0c;结合Grad-CAM技术实现目标检测的可视化分析&#xff0c;支持图像、视频和实时摄像头处理。 功能特性 支持多种Grad-CAM方法实时摄像头处理视频文件处理图像文件处理调用简单 环境要求 Python 3.8需要电脑带有…...

五.ubuntu20.04 - ffmpeg推拉流以及Nginx、SRS本地部署

一.本地部署nginx 1.编译ffmpeg&#xff0c;参考这位博主的&#xff0c;编译选项有的enable找不到的不需要的可以直接删除&#xff0c;但是像sdl&#xff08;包含ffplay&#xff09;、h264、h265这些需要提前下载好&#xff0c;里面都有下载指令。 Ubuntu20.04 编译安装 FFmp…...

深度神经网络全解析:原理、结构与方法对比

深度神经网络全解析&#xff1a;原理、结构与方法对比 1. 引言 随着人工智能的发展&#xff0c;深度神经网络&#xff08;Deep Neural Network&#xff0c;DNN&#xff09;已经成为图像识别、自然语言处理、语音识别、自动驾驶等领域的核心技术。相比传统机器学习方法&#x…...

豪越科技消防一体化平台:打通消防管理“任督二脉”

在城市的车水马龙间&#xff0c;火灾隐患如潜藏的暗礁&#xff0c;威胁着人们的生命财产安全。传统消防管理模式在现代社会的复杂环境下&#xff0c;逐渐显露出诸多弊端。内部管理分散混乱&#xff0c;人员、装备、物资管理缺乏统一标准和高效流程&#xff1b;外部监管困难重重…...

【Matlab】-- 基于MATLAB的美赛常用多种算法

文章目录 文章目录 01 内容概要02 各种算法基本原理03 部分代码04 代码下载 01 内容概要 本资料集合了多种数学建模和优化算法的常用代码资源&#xff0c;旨在为参与美国大学生数学建模竞赛&#xff08;MCM/ICM&#xff0c;简称美赛&#xff09;的参赛者提供实用的编程工具和…...

机器学习课程

前言 课程代码和数据文件&#xff1a; 一、机器学习概述 1.1.人工智能概述 机器学习和人工智能&#xff0c;深度学习的关系 机器学习是人工智能的一个实现途径深度学习是机器学习的一个方法发展而来 达特茅斯会议-人工智能的起点 1956年8月&#xff0c;在美国汉诺斯小镇宁静…...

AIGC(生成式AI)试用 28 -- 跟着清华教程学习 - AIGC发展研究 3.0

目标&#xff1a;继续学习 - 信息不对称、不平等、隐私泄露和数据滥用 - 问、改、创、优 - “概率预测&#xff08;快速反应&#xff09;”模型和“链式推理&#xff08;慢速思考&#xff09;”模型 - 思维滞环现象解决思路&#xff1a;1.调整提问&#xff1a;改变问题方式&…...

问题:md文档转换word,html,图片,excel,csv

文章目录 问题&#xff1a;md文档转换word&#xff0c;html&#xff0c;图片&#xff0c;excel&#xff0c;csv&#xff0c;ppt**主要职责****技能要求****发展方向****学习建议****薪资水平** 方案一&#xff1a;AI Markdown内容转换工具打开网站md文档转换wordmd文档转换pdfm…...

【Java】面向对象之static

用static关键字修饰成员变量 有static修饰成员变量&#xff0c;说明这个成员变量是属于类的&#xff0c;这个成员变量称为类变量或者静态成员变量。 直接用 类名访问即可。因为类只有一个&#xff0c;所以静态成员变量在内存区域中也只存在一份。所有的对象都可以共享这个变量…...

解决:在运行 plt.show()`时,程序会等待你手动关闭图片窗口才能继续往下执行

你这个问题本质是&#xff1a; 在运行 plt.show() 时&#xff0c;程序会等待你手动关闭图片窗口才能继续往下执行。 这其实是 matplotlib 的默认行为 —— 它会弹出一个交互式窗口让你“看完图再走”。 ✅ 为什么会这样&#xff1f; 你在程序中使用了&#xff1a; import mat…...

Anaconda安装-Ubuntu-Linux

1、进入Anaconda官网&#xff0c;以下载最新版本&#xff0c;根据自己的操作系统选择适配的版本。 2、跳过注册&#xff1a; 3、选择适配的版本&#xff1a; 4、cd ~/anaconda_download 5、bash Anaconda3-2024.10-1-Linux-x86_64.sh 6、按Enter或PgDn键滚动查看协议&…...

Linux 配置NFS服务器

1. 开放/nfs/shared目录&#xff0c;供所有用户查阅资料 服务端 &#xff08;1&#xff09;安装nfs服务&#xff0c;nfs-utils包中包含rpcbind&#xff08;rpc守护进程&#xff09; [rootnode1-server ~]# yum install -y nfs-utils # nfs-utils包中包含rpcbind [rootnode…...

css100个问题

一、基础概念 CSS的全称及作用是什么&#xff1f;行内样式、内部样式表、外部样式表的优先级&#xff1f;解释CSS的层叠性&#xff08;Cascading&#xff09;CSS选择器优先级计算规则伪类与伪元素的区别&#xff1f;举例说明!important的作用及使用注意事项如何继承父元素字体…...