Linux 进程的基本概念及描述

目录

0.前言

1. 什么是进程

1.1 进程的定义与特性

1.2 进程与线程的区别

2.描述进程

2.1 PCB (进程控制块)

2.2 task_struct

3.查看进程

3.1 查看进程信息

3.1.1 /proc 文件系统

3.1.2 ps 命令

3.1.2 top 和 htop 命令

3.2 获取进程标识符

3.2.1使用命令获取PID

3.2.2 使用C语言程序获取PID

4. 通过系统调用创建进程

4.1 认识 fork

4.2 代码实践

5.小结


(图像由AI生成) 

0.前言

在上一篇博客中,我们介绍了冯诺依曼体系结构与操作系统的基本概念,深入探讨了计算机是如何执行程序的。本篇博客将继续这一话题,聚焦于操作系统的核心概念之一——进程。进程是操作系统管理程序运行的基本单位,理解进程的概念有助于深入掌握操作系统的运行机制。

1. 什么是进程

进程是操作系统中最基本的执行单位。它指的是一个已经加载到内存并正在执行的程序实例。进程不仅仅是程序本身,还包括程序在运行过程中所需的各种资源,如CPU时间、内存空间、文件描述符等。

1.1 进程的定义与特性

从定义上来说,进程是一个正在执行的程序的实例。每个程序在运行时至少会生成一个进程,不论是用户启动的应用程序,还是操作系统后台运行的服务。进程具有以下几个显著特性:

  • 动态性:程序是静态的文件,而进程是程序在系统中运行时的动态实体。操作系统管理进程的调度、暂停和终止,保证系统中多个进程能够并发执行。
  • 独立性:每个进程都有独立的地址空间,进程之间无法直接访问彼此的内存。这样的独立性保证了进程的稳定运行,避免其他进程的错误或崩溃影响当前进程。
  • 并发性:操作系统可以让多个进程“同时”运行,这种并发性是通过时间分片(时间片轮转)等调度策略实现的,实际上是在CPU快速切换执行不同进程。

1.2 进程与线程的区别

在理解进程的概念时,容易与线程混淆。进程和线程虽然都涉及程序的执行,但它们有显著的区别:

  • 资源分配:进程是系统资源分配的基本单位,每个进程拥有独立的内存空间和系统资源。而线程是进程中的执行单元,多个线程共享同一个进程的资源。
  • 调度单位:进程是操作系统调度的基本单位,系统通过调度进程来实现多任务处理。线程则是进程内部的调度单位,线程的调度发生在进程内部。
  • 通信方式:由于进程之间拥有独立的地址空间,它们之间的通信通常需要通过复杂的机制如进程间通信(IPC),如管道、共享内存等。而线程共享进程的地址空间,线程之间的通信较为简单。

2.描述进程

在操作系统中,进程的信息被存储在一个数据结构(即PCB,进程控制块)中。这个数据结构包含了进程运行所需的所有关键信息,用以管理和调度进程。在Linux系统中,这个数据结构被称为task_struct。通过task_struct,内核能够全面掌握每个进程的状态、资源以及执行情况。

2.1 PCB (进程控制块)

进程控制块(Process Control Block,简称PCB)是操作系统用于描述和管理进程的关键数据结构。PCB包含了进程的所有属性,能够让操作系统跟踪和控制每一个进程的生命周期。在不同的操作系统中,PCB的实现略有不同。在Linux中,PCB以task_struct结构体的形式存在。

PCB的作用可以理解为进程的属性集合,每个进程在创建时,系统都会生成对应的PCB。PCB中存储的进程信息包括:

  • 进程ID(PID):用于唯一标识每个进程。
  • 进程状态:当前进程的运行状态,例如运行中、阻塞中或等待中。
  • 进程优先级:确定进程在调度中的优先顺序。
  • 程序计数器:存储着进程下一条即将执行的指令地址。
  • CPU寄存器:保存进程在暂停时的上下文,以便在重新调度时能够继续运行。
  • 内存信息:包括进程的地址空间和所占用的内存块。
  • I/O设备状态:与进程关联的输入输出设备信息。

2.2 task_struct

在Linux操作系统中,描述进程的核心数据结构是task_struct。它是一种复杂的结构体,包含了与进程相关的所有信息。每个正在运行的进程在内存中都有一个task_struct实例,操作系统通过它来跟踪和管理进程。

以下是task_struct的结构体定义的一个简化版本,它展示了主要的进程信息字段:

struct task_struct {
    volatile long state;    // 进程状态
    pid_t pid;              // 进程ID
    pid_t tgid;             // 线程组ID
    struct mm_struct *mm;   // 内存管理信息
    struct task_struct *parent; // 父进程
    struct list_head children;  // 子进程链表
    unsigned int rt_priority;   // 实时优先级
    unsigned int policy;        // 调度策略
    struct files_struct *files; // 进程打开的文件
    struct fs_struct *fs;       // 文件系统信息
    // 其他字段省略
};

task_struct结构体中的字段可以大致分为以下几类:

  • 标识符:每个进程都有唯一的进程标识符(PID)以及线程组ID(TGID)。这些标识符用于区分进程,并用于进程之间的操作。

  • 状态:进程的状态由字段state表示。它记录了进程当前是处于运行、就绪、阻塞、终止等状态之一。此外,进程的退出代码和退出信号等信息也存储在相关字段中。

  • 优先级rt_priority用于表示实时进程的优先级,而policy字段定义了进程的调度策略,如实时调度或普通调度。进程的优先级决定了它在调度中的优先程度。

  • 程序计数器:进程即将执行的下一条指令的地址通过程序计数器保存,保证在进程调度时,能够从上次暂停的位置继续执行。

  • 内存指针mm字段指向内存管理结构体mm_struct,该结构体包含了与进程相关的内存信息,如程序代码段、堆栈、数据段以及与其他进程共享的内存块。

  • 上下文数据task_struct中的寄存器上下文保存了进程暂停时的处理器寄存器内容,确保在进程恢复时能够继续之前的计算。

  • I/O状态信息files字段保存了进程当前打开的文件列表,而fs字段则包含了与进程相关的文件系统信息。这些字段提供了进程与I/O设备之间的交互信息。

  • 记账信息:进程在运行期间的资源使用情况也会被记录,如使用的CPU时间、时钟周期等。系统可以根据这些信息对进程进行资源限制或计费。

task_struct作为Linux内核中核心的进程描述结构体,通过合理的分类和管理,使得操作系统能够高效地管理进程的生命周期和资源分配。

3.查看进程

在Linux系统中,进程是系统运行的基本单位,操作系统为每个进程分配唯一的标识符和相关的资源。Linux提供了多种方式来查看系统中正在运行的进程信息,方便用户和系统管理员进行管理和调试。

3.1 查看进程信息

Linux系统提供了几种常用的命令和方法来查看进程信息。其中,/proc虚拟文件系统是一个非常重要的机制,它动态地反映了系统中正在运行的进程和内核状态。除此之外,用户还可以使用一些常用命令,如pstophtop等。

3.1.1 /proc 文件系统

/proc目录是Linux中的一个虚拟文件系统,它实时地反映了系统中进程和内核的状态。每个正在运行的进程在/proc目录下都有一个以其进程ID(PID)命名的子目录。在这些子目录中,可以查看与该进程相关的详细信息,如内存使用、打开的文件、状态等。

例如,查看进程ID为24533的进程状态,可以通过以下命令:

cat /proc/24533/status

该命令会显示进程的状态信息,包括PID、进程状态、内存使用、父进程ID等。/proc文件系统是非常灵活且功能强大的工具,适用于查看特定进程的细节。

3.1.2 ps 命令

ps命令是Linux中最常用的查看进程的命令之一。它能够显示当前系统中运行的进程列表及其相关信息。以下是几个常用的ps命令用法:

  • ps -e:列出系统中的所有进程。
  • ps -aux:详细列出所有进程的信息,包括用户、CPU和内存占用、进程ID等。
  • ps -ef:显示进程的完整格式,包括父进程和子进程的关系。

例如:

ps -aux

这条命令会输出系统中所有进程的详细信息,如进程ID、进程状态、用户、CPU占用率等。

3.1.2 tophtop 命令

top是另一个非常有用的实时进程监控工具,它能够动态地显示系统中正在运行的进程,并按CPU、内存占用等进行排序。htoptop的增强版,提供了更友好的图形界面,用户可以更方便地查看和管理进程。

top

该命令会实时显示当前系统的进程和资源使用情况,用户可以根据CPU使用率、内存占用等来进行排序和管理。

3.2 获取进程标识符

在Linux系统中,进程标识符(PID)是每个进程的唯一标识,用来区分系统中的各个进程。可以通过多种方式获取进程的PID,包括使用命令和编写程序代码。

3.2.1使用命令获取PID

  • pidof:获取特定程序的进程ID。例如,获取bash进程的PID:

    pidof bash

                                                        该命令会返回bash进程的PID。

  • ps:通过ps命令结合grep来查找特定进程的PID。例如:

    ps -aux | grep bash

    这条命令会返回与bash相关的所有进程及其PID。

3.2.2 使用C语言程序获取PID

在C语言中,可以使用getpid()系统调用获取当前进程的PID,同时可以使用getppid()获取父进程的PID。以下是一个简单的C语言代码示例,展示如何获取并打印进程的PID和父进程的PID:

#include <stdio.h>
#include <unistd.h>

int main() {
    pid_t pid, ppid;

    // 获取当前进程的PID
    pid = getpid();
    
    // 获取父进程的PID
    ppid = getppid();
    
    // 打印PID和父进程的PID
    printf("当前进程的PID: %d\n", pid);
    printf("父进程的PID: %d\n", ppid);
    
    return 0;
}

编译并运行这段代码后,输出如下:

通过这段代码,可以轻松获取并打印进程的唯一标识符和父进程的标识符。在Linux编程中,了解进程的PID是进行进程间通信、管理进程生命周期的重要步骤。

4. 通过系统调用创建进程

在Linux操作系统中,进程的创建通常是通过系统调用来完成的。系统调用提供了程序与内核交互的接口,fork() 是最常用的创建进程的系统调用之一。

4.1 认识 fork

fork() 系统调用用于创建一个新进程,称为子进程。调用fork()时,系统会复制当前进程,生成一个几乎完全相同的子进程。子进程继承了父进程的所有资源(如文件描述符、内存映射等),但它有自己独立的进程ID(PID)。

  • 父进程与子进程的区别fork()的返回值在父进程和子进程中不同。在父进程中,fork()返回子进程的PID;在子进程中,fork()返回0。这使得父进程和子进程可以根据返回值执行不同的代码。

  • 多进程并发:通过fork()创建子进程后,父子进程会并发执行。操作系统通过调度来分配CPU时间片,确保多个进程能够同时运行。

4.2 代码实践

以下是一个简单的C语言示例,通过fork()创建子进程,并在父子进程中分别输出不同的信息:

#include <stdio.h>
#include <unistd.h>

int main() {
    pid_t pid;

    // 调用fork创建新进程
    pid = fork();

    if (pid < 0) {
        // fork失败
        fprintf(stderr, "fork 失败\n");
        return 1;
    } else if (pid == 0) {
        // 子进程执行
        printf("这是子进程,进程ID: %d\n", getpid());
    } else {
        // 父进程执行
        printf("这是父进程,进程ID: %d,子进程ID: %d\n", getpid(), pid);
    }

    return 0;
}

输出示例

在这个程序中,调用fork()后会创建一个新的子进程,父进程和子进程根据fork()的返回值分别执行不同的代码。父进程打印自己的进程ID和子进程的ID,而子进程只打印自己的ID。

5.小结

进程是操作系统中最重要的概念之一,理解它的基本概念和工作原理有助于更深入地掌握操作系统的运行机制。在Linux中,进程通过PCBtask_struct结构体来描述,进程的创建可以通过fork系统调用来实现。在后续的博客中,我们将继续探讨进程的调度和通信机制。

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

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

相关文章

中原台球展,2025郑州台球展会,中国台球产业链发展大会

阳春三月&#xff0c;万物复苏&#xff0c;商机无限&#xff1b;品牌宣传正当季&#xff0c;产品招商正当时&#xff0c;新品发布好时期。抓住台球发展的这波财富机遇&#xff0c;借助壹肆柒郑州台球展这个超级平台&#xff0c;将品牌和产品快速打造成为覆盖全国市场的顶流。20…

数据治理003-数据域

数据仓库是面向主题&#xff08;数据综合、归类并进行分析利用的抽象&#xff09;的应用。 数据仓库模型设计除横向的分层外&#xff0c;通常也需要根据业务情况进行纵向划分数据域。数据域是联系较为紧密的数据主题的集合&#xff0c;通常是根据业务类别、数据来源、数据用途…

InternLM + LlamaIndex RAG 实践

llamaindexInternlm2 RAG实践 参考教程 正式介绍检索增强生成&#xff08;Retrieval Augmented Generation&#xff0c;RAG&#xff09;技术以前&#xff0c;大家不妨想想为什么会出现这样一个技术。 给模型注入新知识的方式&#xff0c;可以简单分为两种方式&#xff0c;一种…

线性代数(持续更新)

一.矩阵及其计算 1.矩阵的概念 矩阵就是一个数表 元素全是0&#xff0c;是零矩阵&#xff0c;用0来表示 当mn时&#xff0c;称为n阶矩阵&#xff08;方阵&#xff09; 只有一行的叫行矩阵&#xff0c;只有一列的叫列矩阵 只有对角线有元素的叫做对角矩阵&#xff0c;用dia…

(Linux驱动学习 - 4).Linux 下 DHT11 温湿度传感器驱动编写

DHT11的通信协议是单总线协议&#xff0c;可以用之前学习的pinctl和gpio子系统完成某IO引脚上数据的读与写。 一.在设备树下添加dht11的设备结点 1.流程图 2.设备树代码 &#xff08;1&#xff09;.在设备树的 iomuxc结点下添加 pinctl_dht11 &#xff08;2&#xff09;.在根…

HuggingChat macOS 版现已发布

Hugging Face 的开源聊天应用程序 Hugging Chat&#xff0c;现已推出适用于 macOS 的版本。 主要特点 Hugging Chat macOS 版本具有以下亮点: 强大的模型支持: 用户可以一键访问多个顶尖的开源大语言模型&#xff0c;包括 Qwen 2.5 72B、Command R、Phi 3.5、Mistral 12B 等等&…

WebRTC入门

主要参考资料&#xff1a; WebRTC 在 ESP32 系列硬件平台上的实现: https://www.bilibili.com/video/BV1AEHseWEda/?spm_id_from333.337.search-card.all.click&vd_sourcedd284033cd0c4d1f3f59a2cd40ae4ef9 火山 RTC豆包大模型&#xff0c;给用户体验装上银色子弹: https:…

【网络安全】Cookie与ID未强绑定导致账户接管

未经许可,不得转载。 文章目录 前言正文前言 DigiLocker 是一项在线服务,旨在为公民提供一个安全的数字平台,用于存储和访问重要的文档,如 Aadhaar 卡、PAN 卡和成绩单等。DigiLocker 通过多因素身份验证(MFA)来保护用户账户安全,通常包括 6 位数的安全 PIN 和一次性密…

【RabbitMQ】面试题

在本篇文章中&#xff0c;主要是介绍RabbitMQ一些常见的面试题。对于前几篇文章的代码&#xff0c;都已经在码云中给出&#xff0c;链接是mq-test: 学习RabbitMQ的一些简单案例 (gitee.com)&#xff0c;如果存在问题的话欢迎各位提出&#xff0c;望共同进步。 MQ的作用以及应用…

sentinel原理源码分析系列(一)-总述

背景 微服务是目前java主流开发架构&#xff0c;微服务架构技术栈有&#xff0c;服务注册中心&#xff0c;网关&#xff0c;熔断限流&#xff0c;服务同学&#xff0c;配置中心等组件&#xff0c;其中&#xff0c;熔断限流主要3个功能特性&#xff0c;限流&#xff0c;熔断&…

《OpenCV》—— 指纹验证

用两张指纹图片中的其中一张对其验证 完整代码 import cv2def cv_show(name, img):cv2.imshow(name, img)cv2.waitKey(0)def verification(src, model):sift cv2.SIFT_create()kp1, des1 sift.detectAndCompute(src, None)kp2, des2 sift.detectAndCompute(model, None)fl…

使用 Llama 3.1 和 Qdrant 构建多语言医疗保健聊天机器人的步骤

长话短说&#xff1a; 准备好深入研究&#xff1a; 矢量存储的复杂性以及如何利用 Qdrant 进行高效数据摄取。掌握 Qdrant 中的集合管理以获得最佳性能。释放上下文感知响应的相似性搜索的潜力。精心设计复杂的 LangChain 工作流程以增强聊天机器人的功能。将革命性的 Llama …

在线代码编辑器

在线代码编辑器 文章说明前台核心代码后台核心代码效果展示源码下载 文章说明 采用Java结合vue3设计实现的在线代码编辑功能&#xff0c;支持在线编辑代码、运行代码&#xff0c;同时支持导入文件&#xff0c;支持图片识别&#xff0c;支持复制代码&#xff0c;可将代码导出为图…

《RabbitMQ篇》基本概念介绍

MQ功能 解耦 MQ允许不同系统或组件之间松散耦合。发送者和接收者不需要直接连接&#xff0c;从而提高了系统的灵活性和可维护性。异步处理 使用MQ可以实现异步消息传递&#xff0c;发送者可以将消息放入队列后立即返回&#xff0c;不必等待接收者处理。这提高了系统的响应速度…

Kafka学习笔记(一)Kafka基准测试、幂等性和事务、Java编程操作Kafka

文章目录 前言4 Kafka基准测试4.1 基于1个分区1个副本的基准测试4.2 基于3个分区1个副本的基准测试4.3 基于1个分区3个副本的基准测试 5 Java编程操作Kafka5.1 引入依赖5.2 向Kafka发送消息5.3 从Kafka消费消息5.4 异步使用带有回调函数的生产消息 6 幂等性6.1 幂等性介绍6.2 K…

【BurpSuite】SQL注入 | SQL injection(1-2)

&#x1f3d8;️个人主页&#xff1a; 点燃银河尽头的篝火(●’◡’●) 如果文章有帮到你的话记得点赞&#x1f44d;收藏&#x1f497;支持一下哦 【BurpSuite】SQL注入 | SQL injection&#xff08;1-2&#xff09; 实验一 Lab: SQL injection vulnerability in WHERE clause…

基于微信的乐室预约小程序+ssm(lw+演示+源码+运行)

摘 要 随着社会的发展&#xff0c;社会的方方面面都在利用信息化时代的优势。互联网的优势和普及使得各种系统的开发成为必需。 本文以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;它主要是采用java语言技术和mysql数据库来完成对系统的设计。整个…

字体文件压缩

技术点 npm、html、font-spider 实现原理 个人理解&#xff1a;先引入原先字体&#xff0c;然后重置字符为空&#xff0c;根据你自己填充文字、字符等重新生成字体文件&#xff0c;因此在引入的时候务必添加自己使用的文字、字符等&#xff01;&#xff01;&#xff01; 实…

TDengine 流计算与窗口机制的深度解析:揭示计数窗口的关键作用

在 TDengine 3.2.3.0 版本中&#xff0c;我们针对流式计算新增了计数窗口&#xff0c;进一步优化了流式数据处理的能力。本文将为大家解读流式计算与几大窗口的关系&#xff0c;并针对新增的计数窗口进行详细的介绍&#xff0c;帮助大家进一步了解 TDengine 流式计算&#xff0…

解决MySQL报Incorrect datetime value错误

目录 一、前言二、问题分析三、解决方法 一、前言 欢迎大家来到权权的博客~欢迎大家对我的博客进行指导&#xff0c;有什么不对的地方&#xff0c;我会及时改进哦~ 博客主页链接点这里–>&#xff1a;权权的博客主页链接 二、问题分析 这个错误通常出现在尝试将一个不…