单进程的术语大全的庖丁解牛
·
核心内核:单进程,就是程序在操作系统里只创建一个进程实例,整个程序所有逻辑、内存、文件描述符,全部归属这一个进程。类比:一间独立小作坊,只有一个车间,一套工作台,所有活都在这个车间里完成;没有新开别的车间。PHP-CLI简单脚本、Nginx单进程模式、早期简单服务都是单进程。单进程不等于单线程,一个进程内部可以开多个线程。**
一、本源基础术语
- 进程 Process
操作系统资源分配的最小单位,拥有独立虚拟内存空间、独立文件描述符表、pid。 - 单进程 Single Process
程序运行期间,操作系统中仅有一个pid代表本程序,不会fork生成多个子进程。所有业务逻辑跑在这一个进程内部。 - pid 进程ID
内核分配给进程的唯一编号,单进程程序只有唯一pid。 - 进程虚拟地址空间
单进程独享一整套虚拟内存:代码段、数据段、堆、栈、共享库。进程之间内存隔离,别的进程不能直接读写它的内存。 - 单进程多线程
一个进程内部创建多个线程,线程共享进程的堆、文件描述符;每个线程拥有独立栈。Swoole单进程多线程模型就是这个。 - 单进程单线程
进程内只有一条执行流,同一时刻只能执行一段代码。简单PHP CLI脚本默认是单进程单线程。
二、单进程内部内存分区术语
- 代码段 Text段
存放编译后的程序指令,只读,进程内所有线程共享。 - 数据段 Data段
全局变量、静态变量。程序启动就分配。 - 堆 heap
动态申请内存(PHP new、malloc),向上增长,进程内所有线程共享。堆内存由程序自己管理。 - 栈 stack
函数调用、局部变量,每个线程独立栈,函数退出自动回收。 - 共享库 / so
动态链接库,加载到进程虚拟地址空间,多个进程可以复用同一份库代码。
三、单进程的资源术语
- 文件描述符表 fd table
进程私有,这个进程打开的socket、文件、管道全部记录在这张表里。单进程所有IO资源都在这一张fd表,ulimit限制就是限制这个进程最大fd数量。 - 打开文件资源
所有数据库连接、日志文件、网络socket,全部归属这一个进程。进程退出,内核自动关闭这个进程全部fd,释放资源。 - 信号掩码 signal mask
单进程拥有独立信号处理配置。操作系统发送信号(SIGINT、SIGTERM),由这个进程注册的回调处理。 - 进程资源限制 ulimit
限制这个单进程最大打开fd、最大内存、最大CPU时间。
四、执行模型术语
- 串行执行
单进程单线程:代码顺序执行,同一时间只能处理一件任务。一个IO阻塞,整个程序卡住。PHP普通CLI脚本。 - 事件驱动(单进程Reactor)
单进程内部用epoll监听fd,非阻塞IO。不用多进程多线程,在一个进程内同时处理大量连接。Redis就是经典单进程单线程Reactor。
注意:Redis主线程单进程单线程,但后台还有独立子进程做RDB/AOF持久化。
- 任务切换(线程切换)
单进程多线程场景,CPU在进程内不同线程之间切换,属于线程上下文切换,开销远小于进程上下文切换。 - 事件循环 Event Loop
单进程事件驱动程序的核心循环:等待IO事件,事件就绪,执行回调,循环往复。
五、单进程的优缺点术语
- 资源开销低
不需要创建多个进程,没有多进程之间进程上下文切换的巨大开销;内存只有一份进程虚拟空间。 - 内存共享简单
同一个进程内多个线程天然共享堆内存,不用进程间通信IPC,读写共享内存直接访问变量。代价:需要加锁,防止竞态。 - 单点故障
致命短板:只有一个进程。进程一旦崩溃,整个服务直接全部停止。没有别的进程兜底。Redis主线程crash服务就不可用。 - 无法利用多核CPU
单进程单线程:同一时刻只能跑在一个CPU核心,就算机器有8核,其余核心闲置。CPU密集型场景性能上不去。
单进程多线程可以利用多核,线程会被调度到不同核心。
- 阻塞传染
单进程单线程模型,如果业务代码发生阻塞(sleep、同步磁盘IO),整个事件循环卡住,所有连接全部暂停处理。
六、进程间通信IPC(单进程一般不用)
- IPC进程间通信
用于多个进程交换数据。管道、消息队列、共享内存、socket。
单进程内部线程通信直接读写共享变量,不需要IPC。 - fork
创建子进程,一旦fork,就不再是单进程模型。fork之后变成父子两个独立进程。
七、和多进程模型对比术语
- 多进程模型
启动多个独立进程,每个进程有独立pid、独立虚拟内存。PHP-FPM就是多进程。进程之间内存隔离。 - 进程上下文切换
操作系统从进程A切到进程B,需要切换整个虚拟内存页表,开销很高。单进程模型没有进程上下文切换。 - 写时复制 COW
fork子进程时的机制,父子进程一开始共享内存,一方修改内存才复制页面。单进程不存在COW。
八、工程场景术语
- Redis单进程主线程
经典面试例子:Redis网络事件、命令解析都在单进程单线程,持久化交给fork出来的子进程。 - PHP单进程Swoole
Swoole可以配置单进程多线程模式,一个进程内开启多个worker线程。 - 守护进程daemon
单进程也可以变成daemon,脱离终端后台运行。 - 内存泄漏
单进程长时间运行,持续申请内存不释放,内存只会持续上涨。没有其他进程分担,只能重启进程释放全部内存。
九、认知误区术语
- 误区:单进程=单线程
纠正:单进程只是只有一个进程,内部可以多个线程。进程和线程是两层概念。 - 误区:单进程就不能用多核CPU
纠正:单进程多线程可以调度到多个CPU核心;单进程单线程只能占用单个核心。 - 误区:单进程一定性能差
纠正:IO密集型场景,事件驱动单进程单线程性能极高(Redis),瓶颈不在CPU,在网络IO。CPU密集型场景才受限于单核。 - 误区:单进程内部线程崩溃不影响整个进程
纠正:一个线程段错误crash,整个进程直接退出,所有线程一起挂掉。 - 误区:单进程不能监听多个socket
纠正:epoll可以在一个进程里监听成千上万个fd,同时管理大量TCP连接,Redis就是这样。
类比串联
单进程 = 一间独立作坊
- 进程:作坊本身,拥有独立厂房(虚拟内存);
- 单进程单线程:作坊里面只有1个工人,一次只能干一件活;遇到等待(IO),工人原地不动,所有任务停滞;
- 单进程多线程:作坊里多个工人,共用同一套仓库(堆内存),每个人有自己的工作台(线程栈);
- 事件循环:工人不停看消息看板epoll,哪个订单就绪处理哪个;
- 单点故障:作坊一旦失火,所有工作全部停止;
- 多进程:开很多间独立作坊,每一间互相隔离,一间着火其他还能继续干活。
庖丁解牛一句话总结
单进程指操作系统只分配一个pid、一套独立虚拟内存空间的程序实例;单进程可以是单线程,也可以是多线程;单进程单线程无法利用多核CPU;事件驱动单进程模型擅长IO密集场景,无进程上下文切换开销;缺点是单点故障,进程崩溃服务整体不可用。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)