Review
- 2024-10-05 14:50
[!Summary]
- 进程 是资源分配的最小单位,线程 是CPU调度的最小单位。
- 进程 之间相互独立,线程 之间共享进程的资源。
- 线程 是比进程 更轻量级的并发执行单元。
优化:多机分布用进程,多核分布用线程
一、Introduction #
进程(Process) #
进程 是操作系统分配资源的基本单位,可以理解为一个正在运行的程序的实例。每个进程都有自己独立的内存空间、文件描述符、以及其他系统资源。
- 独立性: 每个进程都有自己独立的地址空间,一个进程崩溃不会影响其他进程。
- 资源分配: 系统为每个进程分配特定的资源,如CPU时间、内存、文件等。
- 创建开销: 创建进程的开销相对较大,因为需要为其分配资源。
进程间通信:通过IPC(进程间通信)机制,如管道、消息队列、共享内存等。
进程有哪些重要资源 #
- 内存段
- 文件描述符表:用于管理进程打开的文件。
- 信号处理函数:用于处理各种信号。
- 进程ID:唯一标识一个进程。
- 当前工作目录:进程当前的工作目录。
- 用户ID和组ID:表示进程的所有者。
- 环境变量:进程的环境变量。
进程内存段主要包括 #
- 代码段(Text Segment):存放程序的可执行指令。
- 数据段(Data Segment):存放全局变量和静态变量。
- 堆(Heap):动态分配内存的区域,用于存放程序运行时动态申请的内存块。
- 栈(Stack):用于存储函数调用、局部变量、返回地址等信息。
线程(Thread) #
线程 是进程的一个执行单元,是CPU调度和分派的基本单位。一个进程可以包含多个线程,这些线程共享进程的资源。
- 轻量级: 线程比进程更轻量级,创建线程的开销较小。
- 并发: 多个线程可以在同一个进程中并发执行,提高程序的效率。
- 共享: 线程共享进程的内存空间和资源,但每个线程都有自己的栈空间。
线程间通信:可以直接读写进程数据,通信更简单高效。
线程共享进程的资源包括 #
- 代码段:所有线程共享同一个代码段。
- 数据段:所有线程共享同一个数据段,即全局变量和静态变量。
- 堆:所有线程共享同一个堆,但每个线程申请的内存块是独立的。
- 打开的文件:所有线程共享进程打开的文件。
- 信号处理函数:所有线程共享相同的信号处理函数。
- 环境变量:所有线程共享相同的环境变量。
线程独占的资源: #
- 栈(运行时段):每个线程都有自己的栈,用于存储函数调用、局部变量、临时变量等信息。
- 程序计数器:每个线程都有自己的程序计数器,指示下一条要执行的指令。
- 寄存器:每个线程都有自己的寄存器组,用于保存临时数据。
| 特点 | 进程 | 线程 |
|---|---|---|
| 定义 | 操作系统分配资源的基本单位 | 进程的一个执行单元 |
| 资源 | 独立的内存空间、文件描述符等 | 共享进程的资源 |
| 创建开销 | 较大 | 较小 |
| 并发性 | 进程之间并发 | 线程之间并发 |
| 通信 | 进程间通信IPC | 线程间通信相对简单 |
- 独立性要求高 或 资源消耗大 的任务适合用进程。
- 并发性要求高 或 共享资源多 的任务适合用线程。
扩展 #
- 线程同步: 为了避免多个线程同时访问共享资源导致的数据不一致,需要使用线程同步机制。
- 线程池: 为了避免频繁创建和销毁线程带来的开销,可以使用线程池。
- 死锁: 多个线程在获取资源时相互等待,导致程序无法继续执行。
- 活锁: 线程不断地尝试获取锁,但始终无法获得,导致程序无法取得进展。
- 饥饿: 一个线程一直得不到CPU时间,无法获取锁。
线程同步机制 #
线程同步机制 是为了协调多个线程在共享资源上的访问,确保数据的一致性而采取的一系列方法。当多个线程同时访问共享数据时,如果没有同步机制,可能会导致数据混乱,甚至程序崩溃。
常用的线程同步机制(同步原语) #
- 互斥锁(Mutex):
- 任何时候只有一个线程可以获得锁。
- 获得锁的线程可以访问共享资源,其他线程必须等待。
- 释放锁后,其他线程才能获取锁。
- 信号量(Semaphore):
- 是一种更通用的同步机制,可以控制对共享资源的访问数量。
- 信号量维护一个计数器,表示可用资源的数量。
- 当计数器大于0时,线程可以获取资源;当计数器为0时,线程必须等待。
- 条件变量(Condition Variable):
- 与互斥锁配合使用,允许线程在满足特定条件时被唤醒。
- 线程可以等待一个条件变量,直到另一个线程通知该条件变量。
- 读写锁(Reader-Writer Lock):
- 允许多个线程同时读取共享数据,但同一时刻只能有一个线程写入共享数据。
- 屏障(Barrier):
- 确保多个线程都到达某个点后才能继续执行。
线程同步的应用场景 #
- 共享变量保护: 保护多个线程共享的变量不被同时修改。
- 生产者消费者问题: 生产者线程生产数据,消费者线程消费数据,需要同步机制来协调生产和消费。
- 读者写者问题: 多个线程同时读取共享数据,但同一时刻只能有一个线程写入共享数据。
- 哲学家就餐问题: 多个哲学家共享筷子,需要同步机制来避免死锁。