Linux6.1中为什么用Radix树替换位图(bitmap)来管理进程pid

简介: 在过去的几十年中,Linux内核为了有效地管理进程,采用了位图(bitmap)数据结构来记录和跟踪进程的PID。我们知道Linux支持的最大进程数量为65535个,那么用位图来表示的话只需要16位bit就够了,这大大节约了内存空间,随着系统规模的扩大和复杂性增加,尤其是云计算、容器等新兴虚拟化技术大爆发的时代中,操作系统经常会在短时间内快速创建或者销毁大量进程,在这种场景下位图的全面查找时性能问题就逐渐暴露出来了。为了解决这些问题,Linux内核逐渐采用radix树(radix-tree)来替代位图,对进程PID进行管理,这个替换的思路就是用空间换时间。

在过去的几十年中,Linux内核为了有效地管理进程,采用了位图(bitmap)数据结构来记录和跟踪进程的PID。我们知道Linux支持的最大进程数量为65535个,那么用位图来表示的话只需要16位bit就够了,这大大节约了内存空间,随着系统规模的扩大和复杂性增加,尤其是云计算、容器等新兴虚拟化技术大爆发的时代中,操作系统经常会在短时间内快速创建或者销毁大量进程,在这种场景下位图的全面查找时性能问题就逐渐暴露出来了。为了解决这些问题,Linux内核逐渐采用radix树(radix-tree)来替代位图,对进程PID进行管理,这个替换的思路就是用空间换时间。

Radix树及在Linux pid中的使用方式简介

radix tree是一种多叉搜索树,树的叶子结点是实际的数据条目。每个结点有一个固定的、2^n指针指向子结点。Radix树的基本概念如下:

1.节点

Radix树由节点组成,每个节点表示一个键值。

2.边

每个节点有零个或多个子节点,这些子节点通过边相连。

3.层级

从根节点到任意一个节点的路径上的节点数量称为该节点的层级。

4.深度

Radix树的深度是指根节点到任意一个节点的最长路径上的节点数量。

5.Radix树在Linux Pid中的具体应用方式

如我们刚刚所说Linux中的进程数量最大就是2^16个。在LinuxPID中使用时Radix树的深度固定为3,其中建模方式就是把16位的数据分为三组,其中第一层、第二层和第三层分别表示PId的前4位,中6位及后6位。

假设在一个操作系统中已经用掉了0-3个进程PID,此时新进程开始申请PID的情况举例,此时现有4个进程的PID分为是0000 000000 000000、0000 000000 000001、0000 000000 000010、0000 000000 000011,那么此时Radix树中只有第一层中只0000节点下有子节点000000,而二层子节点000000下有四个子节点000000、000001、000010、000011,此时申请新的PID只需要在0000的二层节点000000下再增加一个叶节点000100即可。

6.Radix树和前缀树的比较

从上面的情况我们可以看到前缀树只支持前缀查询的树形结构,查询时只能找到以该前缀开头的所有字符串。而Radix树则类似于嵌套编码的前缀树,支持全前缀查询的树形结构,查询时可以找到以该前缀开头的所有字符串,并可进一步缩小查询范围。

Radix树相比于BITMAP在PID管理中的优势

1. 海量进程申请时的性能更佳

位图在处理大量PID时,其效率会显著下降。因为位图的每一位只能表示一个PID,所以当系统中有大量进程时,位图会变得非常大,导致内存和CPU资源的大量消耗。而radix树是一种自平衡的树形数据结构,能够高效地管理大量进程PID,无论系统规模大小,都能保持较低的复杂性和良好的性能。

2.PID查询搜索时性能更强

在位图中搜索特定的PID时,需要按位逐一检查,因此搜索时间会随着位图的增大而增加。而radix树具有优秀的搜索性能,通过将PID按照一定的前缀排序并存储在树中,可以快速定位到指定的PID,减少了搜索时间。

3.未来扩展时更具灵活性

目前LINUX的进程数量限定在65535以内,但一旦未来林纳斯同志要打破这一限定,那么位图就要处理变长的PID了,这时需要调整位图的长度,较为繁琐。而radix树可以灵活地管理不同长度的PID,只需要调整树的结构和节点即可。此外,radix树还支持按需扩展和收缩节点,以适应系统负载的变化。

4.并发性更强

在现代多核处理器系统中,对进程PID的管理需要支持并发访问和修改。位图在并发环境中可能会出现竞争条件和死锁等问题。而radix树通过采用锁或其他并发控制机制,能够支持多线程并发访问和修改,提高了系统的并发性能。


综上所述,radix树在管理进程PID方面具有优秀的扩展性、效率、搜索性能、因此,现代Linux内核逐渐采用radix树来替换位图,以更好地满足实际应用场景中对进程PID管理的需求。

相关文章
|
2月前
|
算法 Linux 调度
深入理解Linux操作系统的进程管理
本文旨在探讨Linux操作系统中的进程管理机制,包括进程的创建、执行、调度和终止等环节。通过对Linux内核中相关模块的分析,揭示其高效的进程管理策略,为开发者提供优化程序性能和资源利用率的参考。
110 1
|
4天前
|
存储 网络协议 Linux
【Linux】进程IO|系统调用|open|write|文件描述符fd|封装|理解一切皆文件
本文详细介绍了Linux中的进程IO与系统调用,包括 `open`、`write`、`read`和 `close`函数及其用法,解释了文件描述符(fd)的概念,并深入探讨了Linux中的“一切皆文件”思想。这种设计极大地简化了系统编程,使得处理不同类型的IO设备变得更加一致和简单。通过本文的学习,您应该能够更好地理解和应用Linux中的进程IO操作,提高系统编程的效率和能力。
50 34
|
8天前
|
消息中间件 Linux C++
c++ linux通过实现独立进程之间的通信和传递字符串 demo
的进程间通信机制,适用于父子进程之间的数据传输。希望本文能帮助您更好地理解和应用Linux管道,提升开发效率。 在实际开发中,除了管道,还可以根据具体需求选择消息队列、共享内存、套接字等其他进程间通信方
39 16
|
1月前
|
消息中间件 Linux
Linux:进程间通信(共享内存详细讲解以及小项目使用和相关指令、消息队列、信号量)
通过上述讲解和代码示例,您可以理解和实现Linux系统中的进程间通信机制,包括共享内存、消息队列和信号量。这些机制在实际开发中非常重要,能够提高系统的并发处理能力和数据通信效率。希望本文能为您的学习和开发提供实用的指导和帮助。
118 20
|
2月前
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
121 13
|
2月前
|
SQL 运维 监控
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具
|
2月前
|
运维 监控 Linux
Linux操作系统的守护进程与服务管理深度剖析####
本文作为一篇技术性文章,旨在深入探讨Linux操作系统中守护进程与服务管理的机制、工具及实践策略。不同于传统的摘要概述,本文将以“守护进程的生命周期”为核心线索,串联起Linux服务管理的各个方面,从守护进程的定义与特性出发,逐步深入到Systemd的工作原理、服务单元文件编写、服务状态管理以及故障排查技巧,为读者呈现一幅Linux服务管理的全景图。 ####
|
3月前
|
缓存 算法 Linux
Linux内核的心脏:深入理解进程调度器
本文探讨了Linux操作系统中至关重要的组成部分——进程调度器。通过分析其工作原理、调度算法以及在不同场景下的表现,揭示它是如何高效管理CPU资源,确保系统响应性和公平性的。本文旨在为读者提供一个清晰的视图,了解在多任务环境下,Linux是如何智能地分配处理器时间给各个进程的。
|
3月前
|
网络协议 Linux 虚拟化
如何在 Linux 系统中查看进程的详细信息?
如何在 Linux 系统中查看进程的详细信息?
354 1
|
3月前
|
Linux
如何在 Linux 系统中查看进程占用的内存?
如何在 Linux 系统中查看进程占用的内存?