首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【Linux】进程(2)PCB、task_struct、fork初识

【Linux】进程(2)PCB、task_struct、fork初识

作者头像
mosheng
发布2026-01-14 18:55:50
发布2026-01-14 18:55:50
330
举报
文章被收录于专栏:c++c++

hello~ 很高兴见到大家! 这次带来的是Linux系统中关于进程这部分的一些知识点,如果对你有所帮助的话,可否留下你宝贵的三连呢? 个 人 主 页: 默|笙

一. 描述进程-PCB

进程 = 程序(代码 + 数据)+ PCB

  1. PCB是一个叫做进程数据块的数据结构,它存储着一个进程里面所有的属性,类似这个进程的身份证。
  2. 在Linux系统里面PCB是一个结构体,也就是接下来所要讲的task_struct这个结构体。所有运行中的进程都以task_struct双链表的形式存在于内核里。
  • PCB != task_struct,task_struct只是PCB的一种

二. task_struct

1. 内容属性

1.1 标识符
  1. 每一个进程都会被分配一个唯一的标识符id,用来区分不同的进程。我们用命令getpid来获取一个进程的pid。
  2. 在一个进程里可以创建另一个进程,这个被创建的进程叫做子进程,而创建它的进程叫做父进程。task_struct里面还会存储一个进程的父进程的id。我们用命令getppid来获取一个进程的父进程。
1.2 状态 + 优先级 + 程序计数器 + 内存指针 + I/O状态信息 + 记账信息
  1. 状态信息:代表程序是否正在运行,暂停或退出。一般会用一个整型值来表示这几个状态。
  2. 优先级信息:相对于其他进程当前进程的优先级。它决定了进程被调度执行的顺序和频率。
  3. 程序计数器:它存储的是程序即将执行的下一条代码的地址。它能够保证进程能够恢复执行的位置。
  4. 内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针。
  5. I/O状态信息:包括显⽰的I/O请求,分配给进程的I∕O设备和被进程使用的文件列表。
  6. 记账信息:可能包括处理器时间总和,使⽤的时钟数总和,时间限制,记账号等。
1.3 上下文数据
  1. 在进程运行时对应的PCB里面的数据不是实时更新的,像上下文数据只会在上下文切换时才会保存。
  2. cpu里面是有一套寄存器的,这些寄存器会存储当前进程的运行状态,这个是会随着进程的运行实时更新的。
  3. cpu只有一个,也只有一套寄存器,这意味着单个cpu无法同时处理多个进程
  4. 一个进程执行代码,占用cpu,难道要等这个进程的代码执行完才会让出cpu吗?这显然不是的。现代计算机里都会有一个时间片,运行了一定的时间之后就会自动退出,把cpu让出来。这代表进程可能没有执行完就已经把cpu让了出来,因为时间片一到达,就会有进程切换和调度。之后这个寄存器里存储的这个进程的运行状态的所有数据就会被它的PCB里的上下文数据带走。
  5. 为什么一定要带走这份数据呢?因为这个程序是很有可能没有执行完的,如果我下一次又来执行这个进行的代码,难道我要从头开始执行这个程序吗?显然不是的,因为上下文数据把最后运行时的寄存器里面的数据带走了,可以接着运行这个进程。
  6. 比如上下文数据就会带走寄存器里面存储程序计数器的值,这样就知道程序代码执行到哪里了。
  • 上下文数据包含很多内容比如程序计数器,它在进程切换时会带走cpu寄存器里面所有的数据。然后进程恢复时再将这些数据还给寄存器。

2. 查看进程

/proc
  1. 进程的信息可以通过/proc系统文件夹进行查看。下面那些前半部分的数字(PID)还有self对应的就是一个个的进程目录,这些目录里面存储的是进程的属性。
在这里插入图片描述
在这里插入图片描述
  1. 比如查看目录1的内容,里面就是对应进程的属性:
在这里插入图片描述
在这里插入图片描述
ps
  1. 进程信息也可以通过ps和top这些用户级工具来进行获取。
  2. 这里我们创建一个test.c文件如下(忘加<unistd.h>头文件了,最好加上),编译后运行。
在这里插入图片描述
在这里插入图片描述
  1. 我们用指令ps axj | head -1 && ps axj | grep test来查看进程。其中ps axj是用来查看所有进程的,第一行会有列标,所以用head -1来将第一行显示出来,grep test能够筛选出所有进程里面包含test的进程。
  2. 从下面的图片可以看到,用ps axj是能够直接看到PPID、PID等属性的。
  3. 其中除了用’ ; '来分隔指令之外还可以用&&来进行分割。
在这里插入图片描述
在这里插入图片描述
  1. 我们用ls -l查看进程test的具体属性:这里test的PID跟下面的不一样,因为PID是随机分配的,而不是固定的。
在这里插入图片描述
在这里插入图片描述
  1. 这里我们要着重关注一个叫做cwd的符号链接文件,它里面指向的是当前进程的工作路径。当进程打开一个不存在的文件时(比如fopen),这个文件会被创建,且默认会创建在这个当前运行进程的工作路径下面。如果我们修改这个pwd所指向的工作路径,那么新创建的文件也会在新的工作路径下面。

3. getpid、getppid

  1. 之前了解到getpid能够用来获取进程的PID,而getppid可以用来获取一个进程的父进程PID也就是PPID。
  2. 在Linux系统中,一个新的进程往往是通过父进程产生的。
在这里插入图片描述
在这里插入图片描述

3.我们可以看到test.c的父进程PID也就是PPID是17348,那这个17348究竟是哪个进程?我们来看看。

在这里插入图片描述
在这里插入图片描述
  1. PID为17348的是一个叫做bash的进程。bash是目前最主流的命令行解释器。它本质是终端的子进程,负责执行我们输入的命令。也就是运行test这个文件。test也就称为了它的子进程。
在这里插入图片描述
在这里插入图片描述
  1. 使用getpid和getppid:需要包含头文件<sys/types.h>:定义了pid_t等系统类型(用于表示进程 ID)和<unistd.h>:提供系统调用的函数声明(Unix 标准头文件)。它会返回一个pid_t类型的pid或ppid。pid_t类型底层是用整型实现的。但是具体是int还是long这取决于系统架构。
在这里插入图片描述
在这里插入图片描述

三、 初识fork

在这里插入图片描述
在这里插入图片描述
  1. fork是用来创建子进程的函数。
在这里插入图片描述
在这里插入图片描述
  1. fork有两个返回值,一个会返回给父进程,一个会返回给这个新创建的子进程。如果进程创建成功,返回给父进程的会是这个子进程的PID,返回给子进程的会是0,代表创建成功;如果创建失败,返回父进程的是-1,子进程不会创建。
  2. 子进程父进程的代码是共享的,本质也就是在子进程创建时,它的task_struct也会指向父进程的代码和数据(这份代码是只读的,也就意味着共享无风险。这就代表着fork(如果子进程创建成功)之后的代码会执行多次。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  1. 可以看到,有两个不一样的PID,说明有两个进程执行了同一行代码,而且其中一个还是另一个进程的父进程(15681的父进程是15680)。
  2. 如果我们不想让子父进程执行相同的代码,我们就可以利用fork的返回值来进行分流进而达到目的:如果创建成功,返回给子进程的是0,而返回给父进程的是一个大于0的数。
在这里插入图片描述
在这里插入图片描述
  1. 为什么创建成功给父进程返回的是子进程的pid,而给子进程返回的是0?这是因为一个进程的父进程只能有一个,但是子进程可以有多个,它们之间是1:n的关系。如果我身为一个父亲,我肯定要给孩子取不同的名字,不然就认不清了。子进程不需要通过返回值找父进程,而父进程需要通过返回值找子进程,因为父进程能有多个子进程。
  2. fork()是一个函数,可是为什么却返回了两次?这是因为fork函数的实现里面在return之前就已经完成了子进程的创建,那么return自然就会有两次执行,return的本质其实也就是写入操作

今天的分享就到此结束啦,如果对读者朋友们有所帮助的话,可否留下宝贵的三连呢~~ 让我们共同努力, 一起走下去!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-12-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一. 描述进程-PCB
  • 二. task_struct
    • 1. 内容属性
      • 1.1 标识符
      • 1.2 状态 + 优先级 + 程序计数器 + 内存指针 + I/O状态信息 + 记账信息
      • 1.3 上下文数据
    • 2. 查看进程
      • /proc
      • ps
    • 3. getpid、getppid
  • 三、 初识fork
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档