腾讯Java岗实习一面——线程和进程之间资源共享情况,docker进程隔离是怎么实现的

135 阅读3分钟

这是个非常经典的问题,也是牛客上面试Top100的面试题!我们来直观地总结一下 线程和进程之间资源的共享情况


🧠 一、进程和线程定义先对上:

  • 进程(Process):操作系统资源分配的最小单位。
  • 线程(Thread):CPU 调度的最小单位,是进程内的执行单元。

🔍 二、共享情况一览表:

资源进程线程(同一进程下)
内存空间(代码段、堆、全局变量)❌ 不共享✅ 共享
文件描述符(FD)❌ 不共享✅ 共享
用户 ID、组 ID❌ 不共享✅ 共享
栈空间(Stack)❌ 独立❌ 独立(每个线程有自己的栈)
程序计数器(PC)❌ 独立❌ 独立(控制执行流)
信号处理方式❌ 不共享✅ 共享
当前工作目录❌ 不共享✅ 共享
父进程 PID❌ 不共享✅ 共享(因为在同一进程内)

✅ 所以,总结一句话:

同一进程下的多个线程:共享内存和文件资源,但每个线程都有自己的栈和执行流。

而不同进程之间,默认是完全隔离的,除非使用进程间通信(IPC)机制。


📌 举个例子来加深理解:

假设你在写一个 Web 服务器(比如 SpringBoot + Tomcat):

  • 每个请求来时,Tomcat 会启一个新线程处理。
  • 这些线程共享内存中的缓存、数据库连接池、日志对象(heap 区);
  • 但它们各自有自己的调用栈(方法调用顺序、局部变量等);
  • 所以一个线程崩了,不一定会影响别的线程;
  • 但如果线程把共享数据搞乱了(比如多个线程同时改一个变量),就可能引发线程安全问题 🧨。

Docker 的进程隔离能力是其最核心的功能之一,它通过 Linux 内核提供的一系列技术 实现进程之间的「隔离」,主要包括:


🧱 一、Docker进程隔离关键技术

技术作用
Namespaces(命名空间)实现资源隔离
Cgroups(控制组)实现资源限制
UnionFS / OverlayFS实现镜像层叠、文件系统隔离
Seccomp / AppArmor / SELinux安全限制,防止容器越权操作宿主机

🧠 二、进程隔离的核心:Namespaces

Docker 利用 Linux 的 Namespaces 实现容器内的进程和宿主机、其他容器进程的隔离。主要的几种:

1. PID namespace(进程号隔离)

  • 容器中的进程有自己独立的 PID 编号。
  • 宿主机可以看到容器的所有进程,但容器内只能看到自己的。
  • 容器内的 init 进程通常是 PID 1。

2. NET namespace(网络隔离)

  • 每个容器拥有独立的网络设备(如 eth0)、IP、端口等。
  • 宿主机或其他容器要访问,需要通过 bridge / host 网络模式等。

3. MNT namespace(挂载点隔离)

  • 容器看到的是自己的文件系统挂载点。
  • 宿主机上的目录可以通过 -v--mount 映射到容器中。

4. UTS namespace(主机名隔离)

  • 容器可以有自己的 hostname,不影响宿主机。

5. IPC namespace(进程间通信隔离)

  • 不同容器的共享内存、信号等 IPC 资源是隔离的。

6. User namespace(用户权限隔离)

  • 容器内的 root 用户可以被映射为宿主机的普通用户,增强安全性(但默认关闭)。

💡 三、Cgroups(控制组)限制资源

  • 限制每个容器的 CPU、内存、磁盘 IO、网络带宽等资源
  • 防止某个容器把系统资源吃光

例如:

docker run --cpus=1 --memory=512m ubuntu

就利用了 cgroups 来限制容器的资源。


🧊 四、总结一句话:

Docker 的进程隔离是通过 Linux 的 Namespaces 实现“看不见彼此”,通过 Cgroups 实现“抢不到资源”,再配合文件系统隔离和安全机制,构建了一个像“轻量级虚拟机”的容器环境。


如果你想深入了解某个 namespace 或在宿主机上实验一下,我也可以手把手演示 👨‍💻