百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Linux进程深度解析(1):进程结构、内存布局与资源管理

gudong366 2025-07-23 15:01 4 浏览

0.简介

进程是系统执行的核心单元,理解进程是我们诊断性能问题、开发高并发程序的基础。Linux进程深度解析系列将会从原理角度对进程进行深入分析,帮助读者系统的理解其设计的思路,让读者在理解原理的基础上同时能对自己的设计有借鉴意义。整体系列规划如下(从基础到核心机制再到实战),可能会增加或减少。

进程结构(本文)→ 2. 创建/终止原理 → 3. 调度策略 → 4. IPC机制 → 5. 多进程实战 → 6. 容器与进程隔离

本文就是第一篇,主要讲述进程的表示、内存的分布以及资源的管理。

1.进程的基本概念和生命周期

要理解进程的概念,我们可以回到当时的背景,根据操作系统的演变,理解其产生的原因。早期的计算机只能“独占式”的运行,这就导致CPU时间被大量的浪费;此时就提出了批处理的系统,内存中放多个程序,但是依赖于程序自己让出CPU,这就导致一个程序如果卡死,整个系统就瘫痪了;面对这种情况,分时系统应运而生,分时系统产生后,就需要一个概念去对各个运行的程序进行调度,进程应运而生(也就是增加了一层动态的抽象),后面又经历了多道程序设计,进程概念愈发成熟。

有了上面的描述,我们可以总结进程就是为了方便管理提出的程序运行的实例,有了它就可以对不同程序执行做统一的管理。

接下来我们来看进程的生命周期,可以从进程的状态来看:

状态

符号

说明

运行 (Running)

R

进程正在 CPU 执行或等待 CPU 调度(就绪状态),其通过当前任务指针来区分。

可中断睡眠 (Interruptible Sleep)

S

进程在等待某个事件(如 I/O 完成),可被信号唤醒。

不可中断睡眠 (Uninterruptible Sleep)

D

进程在等待硬件 I/O(如磁盘写入),不能被信号唤醒(避免数据损坏)。

停止 (Stopped)

T

进程被暂停(如 Ctrl+Z 或 SIGSTOP 信号),可恢复(SIGCONT)。

中止/僵尸 (Zombie)

Z

进程已结束,但父进程尚未回收其资源(wait() 未调用)。

死亡 (Dead/X)

X

进程完全终止(资源已释放),内核不会保留该状态(仅短暂存在)。


2.进程的结构剖析(基于linux 5.10)

在linux系统中,进程通过task_struct结构来进行管理,其可以理解为进程涉及的模块的集合,每个模块又会有自己的结构体,同时带有封装和分治的思想,其部分如下,可以看到其存在链表来连接各个进程,这个在进程调度会详细描述。

struct task_struct {
volatile long state;	/*进程状态 -1 unrunnable, 0 runnable, >0 stopped: */
/* Per task flags (PF_*), defined further below: */
unsigned int            flags;
unsigned int            ptrace;
...
unsigned long rt_priority;            //实时优先级
...
struct mm_struct *mm;
struct mm_struct *active_mm;   /*内存管理,像内存映射,页表等信息*/


pid_t pid;                     //进程id
pid_t tgid;                    //进程组id


...
/* Real parent process: */
struct task_struct __rcu    *real_parent;
/* Recipient of SIGCHLD, wait4() reports: */
struct task_struct __rcu    *parent;


struct list_head children;	        /* 子进程列表 */
struct list_head sibling;	        /* 兄弟进程列表 */
...


struct fs_struct *fs;                //文件系统信息
struct files_struct *files;            //打开的文件信息
...
/* VM state: */
struct reclaim_state        *reclaim_state;
struct backing_dev_info     *backing_dev_info;
struct io_context       *io_context;


//信号处理
struct signal_struct *signal;               
struct sighand_struct  __rcu *sighand;
...


/* CPU-specific state of this task: */
struct thread_struct        thread; 
};

3.进程内存布局

本节我们来从进程内存布局描述以及查看来了解相关内容,其整体布局如下:

1)文本段:程序代码的映射。

2)初始化数据段:在程序运行初期进行过初始化的数据。

3)未初始化数据段:在程序运行初期没有初始化的变量。

4)堆:动态分配的区域,向上增长。

5)栈:存储局部变量,临时变量,函数调用压栈等,向下增长。

我们可以通过下面的几个方式去查看内存布局:

1)使用  pmap -p  pid
2)使用  cat /proc/<pid>/maps
3)查看静态的程序,可以使用readelf,这个后面编译相关系列会详细讲解

4.进程资源管理

1)cpu资源管理:和调度算法相关,查看和修改可以使用如下命令。

ps -eo pid,ppid,comm,ni,pri,rtprio | grep <进程名>  # 查看调度参数
chrt -p 99 <pid>  # 设置进程为实时调度(优先级99)

2)内存资源管理:通过分页机制进行内存控制(通过页表映射物理地址,通过缺页中断加载物理页);内存不足时,内核通过oom_killer选择 "最该被杀" 的进程(参考/proc/<pid>/oom_score);可通过/etc/security/limits.conf配置进程内存限制。

top -p <pid>  # 查看进程内存占用
cat /proc/<pid>/status | grep -E "VmRSS|VmSize|OomScore"  # 查看内存详情

3)文件描述符管理:文件描述符(fd)是进程访问文件、套接字、管道等资源的整数句柄;每个进程默认最大打开文件数为 1024(可通过ulimit -n修改)。

lsof -p <pid> | wc -l  # 查看进程打开的文件数
cat /proc/<pid>/limits | grep files  # 查看文件描述符限制

4)资源限制与管控:可以使用ulimit来限制单个进程资源(cpu,内存,文件数等);可以通过cgroups限制一组进程资源。

可以看到,进程资源的使用涉及计算机的方方面面,

5.真实例子

我们对一个进程进行实际分析,以mysqld为例:

1)查看进程基本信息

ps -p 636 -o pid,ppid,state,cmd
PID  PPID S CMD
636   491 S /home/openSource/DataBase/mysql/install/bin/mysqld --basedir=/home/openSource/DataBase/mysql/install --datadir=/home/openSource/DataBase/mysql/data --plugin-dir=/home/openSource/DataBase/mysql/install/lib/plugin --log-error=.er

2)查看进程的内存映射

cat /proc/636/maps
56015ce6f000-560160230000 r--p 00000000 08:20 258515                     /home/openSource/DataBase/mysql/install/bin/mysqld
560160230000-560162abe000 r-xp 033c1000 08:20 258515                     /home/openSource/DataBase/mysql/install/bin/mysqld
560162abe000-5601651a1000 r--p 05c4f000 08:20 258515                     /home/openSource/DataBase/mysql/install/bin/mysqld
5601651a2000-560165391000 r--p 08332000 08:20 258515                     /home/openSource/DataBase/mysql/install/bin/mysqld
560165391000-56016572b000 rw-p 08521000 08:20 258515                     /home/openSource/DataBase/mysql/install/bin/mysqld
56016572b000-560165d5f000 rw-p 00000000 00:00 0
560167c8f000-56016a275000 rw-p 00000000 00:00 0                          [heap]
7f0210000000-7f0210021000 rw-p 00000000 00:00 0
7f0210021000-7f0214000000 ---p 00000000 00:00 0
7f0214000000-7f0214021000 rw-p 00000000 00:00 0
7f0214021000-7f0218000000 ---p 00000000 00:00 0
7f0218000000-7f0218021000 rw-p 00000000 00:00 0
7f0218021000-7f021c000000 ---p 00000000 00:00 0
7f021c000000-7f021c021000 rw-p 00000000 00:00 0
7f021c021000-7f0220000000 ---p 00000000 00:00 0
7f0220000000-7f0220021000 rw-p 00000000 00:00 0
...

3)查看进程资源限制

cat /proc/636/limits
Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            8388608              unlimited            bytes
Max core file size        0                    unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             31199                31199                processes
Max open files            8161                 8161                 files
Max locked memory         67108864             67108864             bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       31199                31199                signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0
Max realtime timeout      unlimited            unlimited            us

6.总结

通过本篇我们对进程有了大概的了解,现在来简单总结一下它带给我们的借鉴意义,首先是对于进程概念的抽象,使用统一的模型屏蔽差异,方便维护;其次是隔离原则,我们可以看到进程有自己的空间,每个空间又有不同的职责,通过边界保证安全和稳定;再有就是通过动态的资源管理,可以根据自己的需要进行资源限制,保证效率和成本的平衡。

相关推荐

linux进程间的通信方式有哪些(linux怎么看这个进程在哪个路径下)

管道通信(PIPE)两个进程利用管道进行通信时.发送信息的进程称为写进程.接收信息的进程称为读进程。管道通信方式的中间介质就是文件.通常称这种文件为管道文件.它就像管道一样将一个写进程和一个读进程连接...

Linux守护进程 daemonize 命令(linux 守护进城)

daemonize:作为守护进程运行命令的工具daemonize是一个命令行实用程序,它作为Unix/Linux守护进程运行命令。daemonize工具是用C语言编写的。大多数程序被设计为作为守护...

linux进程间通信—信号(linux查看进程之间的通信指令i)

Linux环境进程间通信(二)信号(下)一、信号生命周期从信号发送到信号处理函数的执行完毕对于一个完整的信号生命周期(从信号发送到相应的处理函数执行完毕)来说,可以分为三个重要的阶段,这三个阶段由四个...

Linux 上以树状查看文件和进程(linux如何查看进程树)

提供了一些方便的命令,用于以树状分支形式查看文件和进程,从而易于查看它们之间的关系。在本文中,我们将介绍、和命令以及它们提供的一些选项,这些选项可帮助你将注意力集中在要查看的内容上。ps我们用...

文件搜不到?进程理不清?掌握这3个Linux技巧,效率直接翻倍!

哎家人们,今天必须跟你们唠唠Linux里那些“用了就回不去”的效率神器!我猜屏幕前肯定有不少朋友跟我之前一样——明明装着Linux当开发机/服务器,结果每天被命令行折腾得够呛:找个文件翻遍目录,看进程...

如何在 Linux 中使用 PID 号查找进程名称?

在Linux的复杂世界中,进程是系统运行的核心,每个进程都由一个唯一的「进程ID」(PID)标识。无论是系统管理员在排查失控进程,还是开发者在调试应用程序,知道如何将PID映射到对应的进程名称都是一项...

Linux进程深度解析(1):进程结构、内存布局与资源管理

0.简介进程是系统执行的核心单元,理解进程是我们诊断性能问题、开发高并发程序的基础。Linux进程深度解析系列将会从原理角度对进程进行深入分析,帮助读者系统的理解其设计的思路,让读者在理解原理的基础...

Linux 下如何查看进程的资源限制信息?

简介Linux上的cat/proc/$pid/limits命令提供有关特定进程的资源限制的信息,其中$pid是相关进程的进程ID(pid)。该文件是`/proc文件系统的一部分,该...

Linux 8种进程状态及状态转换(linux进程状态切换)

Linux8种进程状态通过psaux可以看到进程的状态。O:进程正在处理器运行,这个状态从来没有见过.S:休眠状态(sleeping)R:等待运行(runable)RRunningorrun...

如何查看linux后台运行的进程?如何查看后台运行进程的状态?

linux系统中挂在后台的进程,如何能够被运维人员知道呢?以及挂在后台的进程当前状态是怎样的?是否可以继续执行?如何杀死一个在后台挂起的进程?后台进程可以通过‘&’符号或nohup命令,让程序进入...

最新保姆级、超详细介绍VMware的使用(一)软件的安装

一、VMware简介VMWare虚拟机软件是一个“虚拟PC”软件,它使你可以在一台机器上同时运行二个或更多Windows、DOS、LINUX系统。与“多启动”系统相比,VMware采用了完全不同的概...

Shell脚本怎么写?(0)(shell脚本怎么写变量)

各位不好意思,最近加班+感冒,有三四天没更新了,python自动化脚本系列总共六期,基本已经囊括了编写python自动化脚本的所有基础函数和语法了。大家如果没看过这个系列的话,可以参考下面的链接:...

用Python从头开发一个自己的Shell(下)

编程派微信号:codingpy平常工作中经常用到shell吧?好不好奇shell的具体执行方式?今天推送的这两篇文章,将利用Python实现一些简单的shell功能。本文原作者为Su...

Linux编程Shell之入门——Shell函数返回值

在Shell中,函数可以通过返回值将结果传递给调用者。返回值可以是一个整数、字符串或其他类型的数据。以下是关于Shell函数返回值的详细介绍:使用return语句在Shell函数中,使用return...

Linux shell编程中易混淆的符号(linux中shell编程详解)

符号主要功能执行环境是否解析变量典型用例()子Shell执行命令子进程是隔离环境操作{}代码块或扩展当前Shell是(代码块内)组合命令或生成序列""弱引用字符串-是含变量...