极高 基础
进程与线程区别#
一句话答案#
进程是资源分配单位(独立地址空间),线程是 CPU 调度单位(共享进程资源),线程切换开销更小。
核心要点
| 维度 | 进程 | 线程 |
|---|---|---|
| 资源 | 独立地址空间 | 共享地址空间(代码/数据/堆)和打开的 fd,各有独立栈和寄存器 |
| 切换 | 大(换页表,TLB 失效) | 小(不切地址空间) |
| 通信 | IPC(管道/共享内存) | 直接共享内存 |
| 崩溃影响 | 不影响其他进程 | 可能导致整个进程崩溃 |
面试回答(2分钟版)
进程是操作系统资源分配的基本单位,线程是CPU调度的基本单位。进程拥有独立的地址空间,包括代码段、数据段、堆和栈,进程间互相隔离,一个进程崩溃不影响其他进程。线程存在于进程内部,同一进程的多个线程共享堆和方法区,但各自拥有独立的栈和程序计数器。这导致几个关键差异:第一,上下文切换开销不同,进程切换需要切换地址空间导致TLB失效(没有 PCID/ASID 时要整体刷掉,x86 Linux 4.14 起用 PCID 可保留部分表项,但缓存仍会被新进程冲掉),线程切换不需要切换地址空间所以开销小得多;第二,通信方式不同,进程间通信需要IPC机制如管道、共享内存、消息队列,线程间可以直接通过共享内存通信但需要注意同步问题;第三,稳定性不同,多进程隔离性强但资源消耗大,多线程效率高但一个线程的异常可能导致整个进程崩溃。在Java中,一个线程默认栈大小1MB(64 位 Linux,这是预留的虚拟地址,物理内存按实际用到的深度才分配),JVM进程内通常创建数百到数千个线程。实际选型上,Nginx用多进程模型保证稳定性,而Java后端通常用多线程模型提高并发效率。
追问与易错
追问方向:
- “线程和协程区别?”→ 线程是 OS 内核调度(MB 级栈、切换涉及内核态),协程是用户态调度(KB 级栈、切换不进内核),协程可创建百万级而线程通常数千
- “一个 Java 线程占多少内存?”→ 64 位 Linux 默认栈大小 1MB(-Xss 可调),但这是预留的虚拟地址,物理内存按实际栈深度按需提交,典型只有几十到几百 KB;真正的限制是线程数多了之后的调度开销、内核 task 结构和 max_user_processes 等上限,高并发场景需要线程池或虚拟线程
- “进程崩溃一定不影响其他进程吗?”→ 通常不影响(地址空间独立),但共享资源场景例外:如崩溃进程持有文件锁未释放、共享内存被破坏、子进程变僵尸消耗 PID
易错点:
- ❌ Linux 内核里进程和线程是两种不同的数据结构——Linux 中两者都是 task_struct,线程就是用 clone(CLONE_VM|CLONE_FILES|…) 创建、共享地址空间的轻量级进程(LWP),调度器一视同仁
- ❌ 多线程就比多进程好——多进程隔离性更强