news 2026/4/23 22:09:05

操作系统是怎么创建进程和线程的?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
操作系统是怎么创建进程和线程的?

操作系统创建进程和线程的底层原理(面试结构化回答)

核心总览

进程是资源分配的基本单位,线程是CPU调度的基本单位。两者创建的核心差异在于:进程创建需分配独立资源(内存、文件描述符等),线程创建仅需分配调度相关的轻量数据结构(TCB、栈),共享所属进程的资源。以下从底层流程、核心数据结构、系统调用三个维度拆解,结合Java开发场景补充关联。

一、操作系统创建进程的底层流程

1. 核心目标

创建一个独立的资源容器,包含运行程序所需的所有资源(内存、文件、IO等),并将其纳入OS的进程调度体系。

2. 关键步骤(以Linux为例,基于fork()系统调用)
步骤底层操作核心细节
1. 分配进程控制块(PCB)OS内核在PCB链表中创建新节点PCB是进程存在的唯一标识,包含:
- 进程ID(PID)、父进程ID(PPID)
- 进程状态(就绪/运行/阻塞)
- 资源指针(指向内存页表、文件描述符表、打开文件列表)
- 调度信息(优先级、时间片、调度队列指针)
- 上下文信息(寄存器组、程序计数器PC)
2. 分配独立资源(1)内存分配:创建独立的虚拟地址空间,通过页表映射到物理内存(Copy-On-Write 写时复制机制优化:fork()时不直接拷贝父进程内存,仅在子进程修改数据时才拷贝对应页,降低创建开销);
(2)文件资源:复制父进程的文件描述符表(指向相同的打开文件),引用计数+1;
(3)其他资源:分配PID、信号处理函数、进程优先级等。
重点:Copy-On-Write(COW)是进程创建的性能优化核心,避免无意义的内存拷贝(比如父进程仅读数据时,子进程无需单独拷贝)。
3. 初始化进程状态将PCB中的进程状态设为「就绪态」,初始化程序计数器(PC)为父进程的指令指针(fork()返回后,子进程从父进程当前执行点继续运行),清空CPU寄存器上下文(等待调度器分配CPU时填充)。注:fork()创建的子进程会复制父进程的内存数据(代码段、数据段、堆),但内核栈和用户栈是独立的(避免调度冲突)。
4. 纳入调度体系将PCB加入OS的就绪队列,等待CPU调度器(如CFS调度器)分配时间片,触发进程上下文切换后开始运行。调度器通过PCB中的优先级、时间片等信息决定调度顺序。
3. 典型系统调用
  • Linux/Unix:fork()(创建子进程,复制父进程资源)+exec()(加载新程序替换子进程内存空间);
  • Windows:CreateProcess()(一站式创建进程+加载程序,不区分fork/exec)。

二、操作系统创建线程的底层流程

1. 核心目标

创建一个轻量级的调度单元,共享所属进程的所有资源,仅新增调度和执行相关的最小化数据结构,实现「并发执行同一程序」。

2. 关键步骤(以Linux POSIX线程为例,基于pthread_create()
步骤底层操作核心细节
1. 分配线程控制块(TCB)内核创建TCB(Thread Control Block),作为线程的唯一标识TCB包含:
- 线程ID(TID)、所属进程PID
- 调度信息(优先级、时间片、调度策略)
- 上下文信息(寄存器组、程序计数器PC)
- 栈指针(用户栈+内核栈的地址)
- 线程状态(就绪/运行/阻塞)
2. 分配独立栈空间(1)用户栈:默认大小为几MB(Linux下默认8MB),用于函数调用、局部变量存储(线程私有,避免数据竞争);
(2)内核栈:用于线程陷入内核态时(如系统调用)保存上下文,大小固定(Linux下默认8KB)。
重点:线程不分配独立内存空间,共享所属进程的代码段、数据段、堆、文件描述符表、信号处理函数等资源。
3. 绑定进程与初始化将TCB关联到所属进程的PCB(通过PID绑定),初始化线程状态为「就绪态」,设置线程的调度参数(继承进程的默认优先级)。线程的资源权限完全继承自父进程,无法独立拥有资源(除非显式通过进程分配)。
4. 纳入调度体系将TCB加入就绪队列,与其他线程(同进程/不同进程)竞争CPU时间片,调度器通过TCB信息进行调度。线程切换开销远小于进程:仅需保存/恢复TCB中的上下文(寄存器、栈指针),无需切换页表(共享进程虚拟地址空间)。
3. 典型系统调用
  • POSIX标准(Linux/Unix):pthread_create()(用户态调用,最终通过clone()系统调用创建内核线程);
  • Windows:CreateThread()
  • Java关联:Java的Thread类本质是「操作系统原生线程」(JDK1.2后废弃用户级线程),通过JNI调用底层系统调用:如Linux下调用pthread_create(),Windows下调用CreateThread(),因此Java线程的创建开销=OS内核线程的创建开销。

三、进程与线程创建的核心差异(面试高频对比)

对比维度进程创建线程创建
资源分配分配独立资源(虚拟内存、文件描述符表、PCB等)不分配独立资源,共享所属进程的所有资源,仅分配TCB和栈
开销大小开销大(内存拷贝、页表创建、资源初始化)开销小(仅初始化TCB和栈,共享资源)
隔离性高(进程崩溃不影响其他进程,资源独立)低(线程共享进程资源,一个线程崩溃可能导致整个进程崩溃)
调度粒度粗(CPU切换进程需切换页表,上下文切换开销大)细(切换线程无需切换页表,上下文切换开销小)
系统调用fork()+exec()(Linux)、CreateProcess()(Windows)pthread_create()(POSIX)、CreateThread()(Windows)
关键解释:为什么线程创建开销远小于进程?
  • 进程创建的核心开销来自「内存拷贝」和「资源初始化」:如fork()需复制父进程的页表、文件描述符表(COW优化后仅减少写操作的拷贝,但仍需创建独立页表结构);
  • 线程创建仅需分配「调度相关的轻量数据」:TCB(几十字节)+ 栈空间(几MB),无需修改内存映射、文件资源等,因此创建速度是进程的10~100倍。

四、Java开发场景的关联延伸(实习生面试加分点)

1. Java线程与OS线程的关系
  • JDK1.2前:Java线程是「用户级线程」(由JVM调度,不依赖OS内核),但存在调度效率低、无法利用多核的问题;
  • JDK1.2后:Java线程改为「原生线程」(内核线程),即每个Java Thread对应一个OS内核线程,调度由OS负责(如Linux的CFS调度器),支持多核并行,且线程状态(RUNNABLE、BLOCKED等)与OS线程状态一一映射。
2. Java创建线程的底层链路
newThread(()->System.out.println("Hello")).start();
  • 调用Thread.start()后,JVM通过JNI调用java.lang.Thread#start0()(本地方法);
  • 底层调用OS的线程创建接口(如Linux的pthread_create()),创建内核线程并绑定TCB;
  • OS将新线程的TCB加入就绪队列,等待CPU调度,执行run()方法中的逻辑。
3. 面试追问应对(体现深度)
  • 问:“Java的线程池为什么能提高性能?”
    答:因为线程创建/销毁的核心开销是OS内核线程的TCB和栈分配/释放,线程池通过复用线程,避免了频繁调用OS系统调用创建线程,减少了内核态与用户态的切换开销。
  • 问:“进程的Copy-On-Write机制具体怎么工作?”
    答:fork()创建子进程时,OS不直接拷贝父进程的物理内存,而是让父子进程共享同一物理内存页,并将这些页标记为「只读」;当任一进程修改内存数据时,OS才会为修改的页分配新的物理内存,拷贝原数据后再允许修改,这样既保证了进程独立性,又减少了创建时的无意义拷贝开销。

总结(面试收尾金句)

  • 进程创建是「资源分配」的过程,核心是建立独立的资源容器;线程创建是「调度单元」的过程,核心是共享资源、轻量初始化;
  • 两者的本质差异决定了:进程适合隔离性要求高的场景(如不同应用程序),线程适合高并发、低开销的场景(如JavaWeb的请求处理);
  • 作为Java开发者,理解底层OS的进程/线程创建机制,能更好地设计高并发系统(如线程池参数调优、避免线程泄露),因为Java的并发模型本质是基于OS内核线程的封装。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/22 18:59:32

宏智树AI:学术写作的智慧引擎,开启科研新范式

宏智树AI是一款专为论文写作设计的 学术写作辅助平台,提供从大纲生成到定稿的一站式服务。其核心功能包括:论文全流程服务‌:涵盖开题报告撰写、文献综述、写作、查重降重(包括AIGC检测)、答辩准备等环节,‌…

作者头像 李华
网站建设 2026/4/23 12:11:39

Dify工作流HTML渲染终极指南:从零基础到专业级展示

Dify工作流HTML渲染终极指南:从零基础到专业级展示 【免费下载链接】Awesome-Dify-Workflow 分享一些好用的 Dify DSL 工作流程,自用、学习两相宜。 Sharing some Dify workflows. 项目地址: https://gitcode.com/GitHub_Trending/aw/Awesome-Dify-Wor…

作者头像 李华
网站建设 2026/4/23 13:58:17

35、脚本编程与bash定制:邮件发送、流程自动化及提示定制全解析

脚本编程与bash定制:邮件发送、流程自动化及提示定制全解析 脚本中发送邮件 在脚本中实现邮件发送功能,有多种方式可供选择,但每种方式都有其特点和适用场景。 首先,使用uuencode方法发送附件时,邮件客户端的支持情况会影响附件的显示效果。像Thunderbird和Outlook这类…

作者头像 李华
网站建设 2026/4/23 12:11:52

safetensors 检查完整

python safetensors 检查是否完整:from safetensors import safe_opendef check_safetensors_basic(path):try:with safe_open(path, framework"pt") as f:keys list(f.keys())print("✅ safetensors 文件结构完整")print(f" tensor 数…

作者头像 李华