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

《Linux系统编程之进程基础》【进程入门】

【进程入门】目录

  • 前言:
  • ---------------进程概念---------------
  • 1. 什么是进程?
    • 小故事:厨房做菜
  • 2. 进程的本质是什么?
  • 3. 什么是PCB?
  • 4. PCB中包含哪些信息?
  • 5. 如何查看进程?
    • 方法一:通过getpid系统调用
    • 方法二:使用top和ps用户级工具
    • 方法三:通过/proc系统文件夹
      • 一、exe
      • 二、cwd(Current Working Directory)
  • ---------------进程创建---------------
  • 1. Linux中进程创建的原则是什么?
  • 2. 如何使用系统调用fork创建子进程?
    • 小故事:细胞分裂
    • ①如何理解“调用一次,返回两次 + 复制特性”?
    • ②关于系统调用fork的灵魂三问?
      • (1)灵魂追问1:
      • (2)灵魂追问2:
    • ③如何理解“独立性”?

在这里插入图片描述

往期《Linux系统编程》回顾:
/------------ 入门基础 ------------/
【Linux的前世今生】
【Linux的环境搭建】
【Linux基础 理论+命令】(上)
【Linux基础 理论+命令】(下)
【权限管理】
/------------ 开发工具 ------------/
【软件包管理器 + 代码编辑器】
【编译器 + 自动化构建器】
【版本控制器 + 调试器】
【实战:倒计时 + 进度条】
/------------ 系统导论 ------------/
【冯诺依曼体系结构 + 操作系统基本概述】

前言:

hi~ 小伙伴们大家好呀!(ノ≧∀≦)ノ✨
前面铺垫了这么久,今天终于要正式开启《Linux 系统编程》的核心之旅啦!而咱们遇到的第一个 “拦路虎”,就是系统编程里的第一座大山🏔️ ——进程!(。•̀ᴗ-)✧🌟

  • 这可不是座小土坡哦~ 进程不仅是入门的关键难点,还和后面的文件、线程等核心内容紧密相连,牵一发而动全身。
  • 所以咱们不会浅尝辄止,我们将会花费很多很多的时间,把它从里到外彻底研究明白,为后续学习打下扎实的基础!💪( ̄︶ ̄)↗

先给大家剧透下今天的学习重点 ——【进程入门】,核心内容主要包括这两块:🎉٩(◕‿◕)۶🎉

  • 进程的概念:将会从全新的视角认识进程 (包含对进程的顶级理解(≧ω≦)ゞ
  • 进程的创建:学会创建进程 (做到知其所以然 🔍( ̄^ ̄)ゞ

---------------进程概念---------------

1. 什么是进程?

进程(Process):是操作系统进行资源分配调度的基本单位。

  • 进程指的是正在运行的程序的一个实例,当我们双击打开一个应用程序:
    • 比如浏览器、音乐播放器时,操作系统就会为这个程序创建一个进程
    • 这个进程包含了程序运行时所需的各种资源以及运行状态等信息
  • 从本质上讲,进程是程序在操作系统中的一次执行活动

小故事:厨房做菜

想象一个餐厅的厨房(操作系统)

  • 程序就像是一份菜谱
    • 它本身是静态的、被动的,只是一堆指令和数据的集合,放在抽屉里不会自己做什么
  • 进程就是厨师真正开始按照菜谱做菜的过程 要完成这个过程,你需要:
    • 工作台(内存):用来放切好的肉丝、笋丝、木耳等原料和中间产物
    • 厨具(CPU):灶台、炒锅、刀,用来真正地执行“炒”、“切”这些动作
    • 原料(数据):猪肉、笋、豆瓣酱等
    • 菜谱(程序代码):告诉厨师每一步该做什么

一个菜谱(程序)可以同时被多个厨师使用,做出多份鱼香肉丝(多个进程)

每个厨师都有自己的工作台和原料,互不干扰。

2. 进程的本质是什么?

看完前面关于进程的介绍,大家是不是觉得自己已经搞懂 “什么是进程” 了?

悄悄告诉你们,其实到这里,我们还没真正触及进程的本质。

前面聊的,只是大家通常认知中的进程 —— 算是 “形” 的层面,今天,咱们就来揭开进程 “神” 的面纱,看看它最核心的本质是什么。


从更底层的结构来看:

进程 = 内核数据结构对象(即进程控制块 PCB) + 程序自身的代码与数据


操作系统需要管理多个被加载到内存中的程序(也就是多个进程),其管理思路遵循 “先描述,再组织” 的核心原则:

  • “先描述”:通过 PCB(在 Linux 中是 struct task_struct)来 “描述” 每个进程的所有属性

    • 比如 :进程 ID、运行状态、资源占用情况等,这样操作系统就能清晰地了解每个进程的具体情况
  • “再组织”:将所有进程的 PCB 以链表等数据结构组织起来(形成 “进程列表”)

    • 如此一来,对进程的管理操作(比如:创建新进程、终止已有进程、调度进程执行等),就转化为对这个链表的 “增加、删除、查询、修改” 操作
      • 创建进程:就是向链表中添加一个新的 task_struct 节点
      • 终止进程:就是从链表中删除对应的节点
      • 调度进程:执行就是调整链表中节点的顺序或者状态等

以存储在磁盘中的可执行程序 cmd 为例,它运行成为进程的过程如下:

  • 首先cmd 以文件的形式存储在磁盘里。当用户执行 ./cmd 命令时,操作系统会把 cmd 的代码和数据从磁盘加载到内存当中
  • 接着操作系统为 cmd 创建对应的 PCB(struct task_struct),并将该 PCB 与加载到内存的代码、数据相关联,此时一个完整的 cmd 进程就被创建出来了
  • 之后,操作系统会依据调度策略,从进程列表中挑选合适的进程(比如:cmd 进程),把 CPU 资源分配给它,使得它的代码能够得以执行

值得注意的是,进程的所有属性,都可以直接或者间接地通过 task_struct 来获取,这也体现了 PCB 作为 “进程核心描述载体” 的重要作用。

在这里插入图片描述

3. 什么是PCB?

PCB 即进程控制块(Process Control Block):是操作系统管理进程的关键数据结构用于记录进程的各种信息,是进程存在的唯一标志。

  • PCB 是操作系统为了管理进程而创建的数据结构,它记录了进程从创建到终止整个生命周期的状态和相关信息
  • 可以将 PCB 理解为进程的 “档案”,操作系统通过这个 “档案” 来对进程进行调度、资源分配以及控制进程的运行

4. PCB中包含哪些信息?

PCB 包含的信息十分丰富,主要可分为以下几类:

  • 标识信息:用于唯一标识一个进程。
    • 进程 ID(PID),它是进程的唯一编号,在系统中起到区分不同进程的作用
    • 父进程 ID(PPID),用于表明该进程的创建者是谁,方便系统进行进程间关系的管理
  • 状态信息:记录进程当前所处的状态。
    • 就绪状态(进程已准备好,等待 CPU 调度执行)
    • 运行状态(进程正在 CPU 上执行)
    • 阻塞状态(进程因等待某一事件,如:I/O 操作完成、信号量等而暂停执行)
  • 资源信息:包含进程运行时所需的各种资源的相关信息。
    • 内存资源,记录进程占用内存的起始地址、大小等,以便操作系统进行内存分配和回收
    • 文件列表,记录进程当前打开的所有文件的信息,包括文件描述符、文件指针等,使得进程能够正确地对文件进行读写等操作
  • 调度信息:与进程调度相关的信息。
    • 进程的优先级,优先级高的进程在调度时会优先获得 CPU 资源
    • 进程的时间片,在分时操作系统中,每个进程被分配一定的 CPU 执行时间,即时间片
  • 上下文信息:当进程因某种原因暂停执行时,需要保存其当前的运行环境,以便在恢复执行时能从断点处继续。
    • CPU 寄存器的值(如程序计数器 PC,它指向下一条要执行的指令地址;通用寄存器,用于暂存数据和地址等)
    • 程序状态字寄存器(PSW,记录程序的运行状态,如运算结果的标志位等)

5. 如何查看进程?

方法一:通过getpid系统调用

getpid:是一个常用的系统调用(system call)主要功能是获取当前进程的进程ID(PID)

  • 每个进程在 Linux 中都有一个唯一的非负整数标识符,即:PID,它就像进程的 “身份证号”,操作系统通过 PID 来区分和管理不同的进程
  • getpid 的作用就是让当前运行的程序能够知道自己的这个唯一标识
  • getpid 是系统调用,需要从用户态切换到内核态执行,由内核查询进程控制块(PCB,即 task_struct)中的 PID 信息并返回

简单说getpid 就是进程 “自我介绍” 的工具,让程序能知道自己在系统中的唯一编号。

在这里插入图片描述
在这里插入图片描述

方法二:使用top和ps用户级工具

ps用于查看当前系统中进程状态的重要工具。

ps 命令其实有很多值得深入探讨的细节,但今天它并不是主角。关于 ps 的学习,我们会在后续的内容中逐步渗透 —— 如果一开始就把 ps 的所有相关知识一股脑列出来,初学的小伙伴很可能难以理解,而死记硬背的话,那就更是与 “融会贯通” 的学习理念背道而驰了)

今天我们就先学习会使用ps吧:


基本语法ps [选项]

  • a选项显示所有终端上的进程,包括其他用户所拥有的进程,不仅仅局限于当前登录用户自己的进程。
    • 例如:在多人使用的服务器上,执行ps a ,就能看到不同用户在各个终端中运行的进程情况
  • j选项以作业格式显示进程信息,会列出与进程组相关的信息。
    • 例如:进程组 ID(PGID)、会话 ID(SID)等。这对于理解进程之间的分组关系、会话关系很有帮助
  • x选项显示没有控制终端的进程。
    • 例如:很多后台服务进程(如:系统守护进程)是脱离终端运行的,ps x 就可以把这些进程展示出来,方便对后台服务进行管理和监控

在这里插入图片描述


思考与探究:为什么执行 ps ajx | grep code.exe 命令时,筛选出来的进程除了 code.exe,总是还会有一个 grep --color=auto code.exe 呢?

  • ps ajx 会先列出系统中当时的进程信息,然后 grep code.exe 作为一个正在运行的命令进程,也会被 ps ajx 捕获到。

    • grep 命令本身在执行 “筛选含 code.exe 关键字的进程” 这个任务,所以它自己的进程信息也会被包含在 ps ajx 的输出里
    • 进而被 grep code.exe 筛选出来,于是就出现了除 code.exe 外,还能看到 grep --color=auto code.exe 的情况
  • 如果想只保留 code.exe 进程,可进一步用 ps ajx | grep code.exe | grep -v grepgrep -v grep 用于排除含 grep 关键字的行


注意事项ps 命令所显示的进程状态是执行命令瞬间的状态

由于进程状态是动态变化的,如果需要持续监控进程状态,可以采用以下两种方式:

  • 使用top命令:它能实时动态地显示系统中各个进程的资源占用情况等信息
  • 使用循环执行的命令while true; do ps ajx | grep code.exe | grep -v grep; sleep 1; done
    • 这条命令会每隔 1 秒执行一次ps ajx | grep code.exee | grep -v grep,持续输出与code.exe进程信息,便于观察其状态变化

在这里插入图片描述

在这里插入图片描述

方法三:通过/proc系统文件夹

/proc:是一个非常特殊的目录,它并非存储在磁盘上的普通文件系统,而是一个虚拟文件系统(procfs)

  • 它由内核动态生成,用于向用户空间提供内核和进程的实时信息

核心特点:

  • 动态性/proc 中的文件和目录并非实际存储在磁盘上,而是由内核在运行时根据系统状态动态创建和更新,当读取这些文件时,内核会实时生成内容
  • 无占用磁盘空间:由于是虚拟文件系统,/proc 不会占用实际的磁盘存储空间(可用 df /proc 查看,会发现其占用为 0)
  • 进程与系统信息的 “窗口”:通过 /proc 可以直接获取内核参数、硬件信息、进程状态等关键数据,是用户与内核交互的重要接口

在这里插入图片描述

一、exe

/proc/[PID]/exe指向进程可执行文件的符号链接。

在这里插入图片描述

二、cwd(Current Working Directory)

/proc/[PID]/cwd是表示某个进程当前的工作目录的符号链接。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在 C 语言中,当使用 fopen 函数创建文件且未指定完整路径(只给出文件名,比如 fopen("hello.txt", "a");)时,文件会在执行程序所在路径下创建。

这可以从进程和当前工作目录(cwd,Current Working Directory)的角度来解释:


进程的当前工作目录(cwd)

  • 在 Linux 等操作系统中,每个进程在运行时都有一个当前工作目录,这个目录记录在 /proc/[PID]/cwd 中([PID] 是进程的 ID)
  • 进程在执行过程中,对于使用相对路径的操作,都是以当前工作目录作为基准路径来进行的

fopen 函数的路径解析机制

fopen 函数在处理文件路径时,会区分绝对路径和相对路径:

  • 绝对路径:当 fopen 的第一个参数传入的是绝对路径(如:fopen("/home/user/hello.txt", "a");)时,操作系统会根据路径从根目录开始查找和访问文件, 比如在上述示例中,就会在 /home/user/ 目录下操作 hello.txt 文件
  • 相对路径:当 fopen 的第一个参数传入的是相对路径(也就是只有文件名,没有从根目录开始的完整路径信息,如:fopen("hello.txt", "a");)时,进程会以当前工作目录为起点去解析这个相对路径

---------------进程创建---------------

1. Linux中进程创建的原则是什么?

在 Linux 系统中,进程的创建遵循 “父子继承” 原则—— 被创建的新进程则称为 “子进程”:

  • 除了系统启动时第一个初始化进程(如:systemd,PID 通常为 1)外
  • 所有进程都是由另一个已存在的进程(即 “父进程”)通过 fork()clone() 等系统调用创建的

值得注意的是,一个父进程并非只能创建一个子进程 —— 它可以通过多次调用 fork() 生成多个子进程,这些子进程共享同一个父进程。

正因为这种 “一个父进程可衍生多个子进程” 的特性,Linux 系统中的所有进程最终会形成一种树状层级结构(即 “进程树”)

  • 进程树的 “根节点” 是系统初始化进程(如:systemd),它是所有进程的 “祖先”
  • 每个进程(除根进程外)都是树中的一个 “节点”,其上层是父进程,下层是它创建的子进程

在这里插入图片描述

-bash 之所以是父进程,原因如下:

1. 终端与 shell 的关系

  • 当你在 Linux 系统中打开一个终端时,系统会自动为你启动一个 shell 进程(通常就是 bash)
  • 这个 shell 进程负责解释你在终端中输入的命令 ,并执行相应的操作
    • 比如:你输入ls命令,bash 就会解析这个命令,并调用系统函数来列出当前目录下的文件和目录

在这里插入图片描述

2. 进程创建逻辑

当你在终端中运行一个可执行程序(图中的code.exe )时:

  • 是由当前的 bash 进程通过fork() 系统调用创建一个子进程
  • 然后在子进程中通过exec() 族函数来执行你要运行的程序

简单来说bash 作为你与系统交互的桥梁,在你运行程序时,它就充当了父进程的角色,负责创建并管理子进程的启动。

2. 如何使用系统调用fork创建子进程?

fork():用于创建新进程。

  • 它是一个非常重要的系统调用
  • 它的核心作用是 从已存在的进程中复制出一个新进程,原进程称为 “父进程”,新进程称为 “子进程”

基本特性

  • 调用一次,返回两次
    • fork() 在父进程中返回子进程的 PID(进程 ID),在子进程中返回 0
    • 若创建失败,在父进程中返回 -1
  • 复制特性
    • 子进程会复制父进程的地址空间(包括:代码数据堆栈等)
    • 但拥有独立的 PID、PPID(父进程 ID)等属性
  • 独立性:子进程创建后,与父进程独立运行,操作系统会调度它们交替执行

小故事:细胞分裂

想象一个细胞(父进程)正在进行有丝分裂

  1. 分裂前:有一个细胞,包含完整的遗传物质(DNA)
  2. 分裂中:细胞复制了自己的全部遗传信息
  3. 分裂后:现在有了两个几乎完全相同的细胞

它们共享着相同的“基因”(代码),但从此以后是独立的生命体,可以各自对外界刺激做出不同的反应(执行不同的代码路径)


在这个比喻中:

  • 细胞分裂这个动作就是 fork() 系统调用
  • 原始的细胞就是父进程
  • 新分裂出的细胞就是子进程
  • 遗传物质(DNA) 就是父进程的代码段、数据段、堆栈、打开的文件描述符等所有资源

①如何理解“调用一次,返回两次 + 复制特性”?

在这里插入图片描述

通过上面的示例,我们能明白这样一个道理:

  • fork() 具有复制特性 —> 父进程和子进程会共享相同的代码

  • 不然的话,子进程是没有办法执行父进程程序里的 printf 语句的

在这里插入图片描述

在这里插入图片描述

②关于系统调用fork的灵魂三问?

关于系统调用fork的灵魂三问?

  1. 为什么 fork 会给父进程和子进程返回各自不同的返回值?
  2. 为什么一个fork会返回两次?
  3. 为什么同一个变量,既等于 0,又大于 0,使得 ifelse 分支看起来像是同时成立了?

刚了解完系统调用fork,现在感觉头好大啊!第三个问题今天先放一放,之后会细说。

(1)灵魂追问1:

fork() 给父进程和子进程返回不同值的设计,是 Linux 内核为了让父子进程能够明确区分自身身份并执行不同逻辑而专门设计的机制

  • 核心目的:区分进程角色
    fork() 的作用是创建子进程,而创建后父子进程会从同一代码位置继续执行。内核需要一种方式让两个进程知道 “自己是谁”—— 是原来的父进程,还是新创建的子进程。
    因此,内核设计为:
    • 给父进程返回子进程的 PID(一个大于 0 的整数),方便父进程后续通过 PID 管理子进程(如:用 wait() 回收资源)
    • 给子进程返回 0,表明它是新创建的子进程

  • 技术实现:基于进程复制的特性
    fork() 会复制父进程的地址空间(包括:变量、代码等),子进程会获得与父进程完全相同的内存副本。
    fork() 执行完成后:
    • 父进程从内核态返回用户态时,内核将子进程的 PID 写入父进程的返回值变量
    • 子进程从内核态返回用户态时,内核将 0 写入子进程的返回值变量(子进程的内存空间独立,因此不会影响父进程)

总结:这种设计使得父子进程能通过简单的条件判断(if (id > 0)if (id == 0))执行不同逻辑,是多进程编程中区分父子进程的关键机制。

(2)灵魂追问2:

fork 函数之所以会 “返回两次”,是由它创建子进程的机制决定的,核心逻辑在于 fork 会复制出一个与父进程几乎完全相同的子进程,之后父子进程会各自独立执行

在这里插入图片描述

③如何理解“独立性”?

进程的独立性,说起来也好理解,举个例子就很清楚:

  • 比如你用电脑时,一边在 VS2022 里写代码,一边用 QQ 音乐听歌
  • 如果 QQ 音乐突然崩溃了,你仍然可以继续在 VS2022 里写代码

这就是进程独立性的直观体现,哪怕是父子进程,就算父进程意外退出,子进程也能继续运行,不会受到直接影响。


从深层原理来看,这种独立性源于两个关键机制:

  1. 进程控制块(PCB)的独立性
    操作系统通过 PCB(Linux 中是task_struct结构体)管理每个进程,每个进程都有自己专属的 PCB,记录着进程的 ID、状态、资源占用等信息,这种独立的 “身份档案” 让操作系统能单独管理每个进程,彼此不会混淆
  2. 内存资源的隔离机制
    • 代码段是只读的,无论是父进程还是子进程,都只能执行代码而不能修改,因此代码不会因某个进程的操作而被破坏,保证了执行逻辑的独立性
    • 数据段默认情况下父子进程会共享(为了提高效率),但一旦有进程尝试修改数据,操作系统会触发 “写时拷贝” 技术 —— 为修改方复制一份独立的数据副本,让其在副本上修改,这样既保证了初始状态下的资源共享效率,又在需要修改时实现了数据隔离,避免相互干扰

正是这些机制,确保了进程之间互不干扰,即使某个进程出现问题,也不会轻易影响到其他进程的正常运行。

在这里插入图片描述

通过这个示例,我们能更直观地理解 pid_t id = fork(); 中返回值 id 为何会是不同的值了,核心原因是:

  • fork() 调用成功后,会创建一个与父进程独立的子进程
  • id 变量会在父进程和子进程中各自拥有独立的副本,操作系统会为两个副本赋值不同的结果

在这里插入图片描述

http://www.dtcms.com/a/609130.html

相关文章:

  • Hello-agents TASK03 第四章节 智能体经典范式构建
  • C++ 二叉搜索树(BST)完全指南:从概念原理、核心操作到底层实现
  • 电子电气架构 --- 哨兵模式初入门
  • 桌面开发,在线%考试管理%系统,基于eclipse,java,swing,mysql数据库。
  • 超融合架构的核心组件与协同机制深度解析
  • 桌面开发,在线%图书管理%系统,基于eclipse,jdk,java,swing,sqlserver数据库
  • 快速学会做网站网站建设公司怎么推广
  • 无需 iTunes 备份与恢复 iPhone 的 2 种方法
  • 【Linux】Ubuntu图形界面崩溃(无法进入)的解决方法汇总
  • Lidar调试记录Ⅳ之Ubuntu22.04+ROS2+Livox_SDK2环境下编译Livox ROS Driver 2
  • 网站收录查询网摘抄一则新闻
  • 做电影网站违法么深圳网站建设10强
  • 荆州北京网站建设如何自己做网页链接
  • 网站建设开发教程视频网站如何建设目录
  • 为企业为什么做网站数据分析师是干嘛的
  • 叶县建设局网站网站快速建设视频
  • 保定 网站制作门户网站如何建设
  • 网站建设基本流程视频网站建站思路
  • 三星官网网站wordpress评论钩子
  • 关于网站开发的外文书籍怎么做网站软件
  • 好一点的网站建设电商代运营公司
  • 给人做网站的公司现在一个天猫店要多少钱
  • 微网站建设哪家好电商网站如何设计内容
  • 关于重新建设网站的请示中国贸易网登录
  • 网站开发的实训周的实训过程网店运营心得体会
  • 网站备案前置审批 成都个人网站建设怎么赚钱
  • 网站设计中超链接怎么做网站优化 合同
  • 嘉兴企业网站制作单页网站规划设计书
  • 临沂网站制作报价宿迁发布最新通告
  • 毕业生对于网站建设感受客户网站开发全流程图