您好,登录后才能下订单哦!
# 线程的相关知识点总结
## 一、线程的基本概念
### 1.1 什么是线程
线程(Thread)是操作系统能够进行运算调度的最小单位,被包含在进程之中,是进程中的实际运作单位。一个进程中可以并发多个线程,每条线程并行执行不同的任务。
与进程相比,线程具有以下特点:
- 线程是进程的一个执行单元
- 线程是处理器调度的基本单位
- 线程共享进程的地址空间和系统资源
- 线程的创建、切换和销毁开销远小于进程
### 1.2 线程与进程的区别
| 特性 | 进程 | 线程 |
|-------------|------------------------|------------------------|
| 基本单位 | 资源分配的基本单位 | CPU调度的基本单位 |
| 开销 | 创建/切换开销大 | 创建/切换开销小 |
| 内存 | 独立地址空间 | 共享进程内存 |
| 通信 | IPC机制复杂 | 可直接读写共享变量 |
| 健壮性 | 一个进程崩溃不影响其他 | 一个线程崩溃导致整个进程终止 |
## 二、线程的实现方式
### 2.1 用户级线程(ULT)
完全在用户空间实现的线程机制,内核无感知:
- 优点:不依赖OS,可定制调度算法
- 缺点:一个线程阻塞会导致整个进程阻塞
- 典型实现:早期Java线程模型
### 2.2 内核级线程(KLT)
由操作系统内核直接支持的线程:
- 优点:多处理器并行,单个线程阻塞不影响其他
- 缺点:线程操作需要系统调用,开销较大
- 典型实现:Windows线程、Linux pthread
### 2.3 混合模型
现代操作系统通常采用混合模式(如N:1、1:1、M:N):
- Linux采用1:1模型(每个用户线程对应一个内核线程)
- Windows 7+采用1:1模型
- Go语言采用M:N模型(goroutine调度器)
## 三、线程的生命周期
### 3.1 线程状态转换
```mermaid
stateDiagram
[*] --> 新建(New)
新建 --> 就绪(Runnable): start()
就绪 --> 运行(Running): 获取CPU
运行 --> 就绪: 时间片用完/yield()
运行 --> 阻塞(Blocked): I/O操作/等待锁
阻塞 --> 就绪: I/O完成/获取锁
运行 --> 终止(Terminated): run()结束/异常
当多个线程并发访问共享资源时,可能导致: - 竞态条件(Race Condition) - 数据不一致 - 死锁/活锁
import threading
lock = threading.Lock()
def safe_update():
lock.acquire()
try:
# 临界区代码
finally:
lock.release()
Semaphore sem = new Semaphore(3); // 允许3个线程同时访问
void accessResource() {
sem.acquire();
try {
// 使用资源
} finally {
sem.release();
}
}
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
// 等待线程
std::unique_lock<std::mutex> lck(mtx);
while(!ready) cv.wait(lck);
// 通知线程
{
std::lock_guard<std::mutex> lck(mtx);
ready = true;
}
cv.notify_all();
死锁四个必要条件: 1. 互斥条件 2. 占有并等待 3. 非抢占条件 4. 循环等待
预防策略: - 破坏任一必要条件 - 使用锁排序(Lock Ordering) - 设置超时(tryLock) - 银行家算法(资源分配前检查安全性)
通过全局变量或堆内存进行通信(需同步):
// 生产者-消费者示例
int buffer[10];
int count = 0;
void producer() {
while(1) {
item = produce_item();
if(count < 10) {
buffer[count++] = item;
}
}
}
通过队列等结构进行线程间通信:
from queue import Queue
msg_queue = Queue(maxsize=10)
def worker():
while True:
item = msg_queue.get()
process(item)
msg_queue.task_done()
UNIX/Linux下的pipe机制:
int fd[2];
pipe(fd);
// fd[0]为读端,fd[1]为写端
参数 | 说明 |
---|---|
corePoolSize | 核心线程数(常驻) |
maximumPoolSize | 最大线程数 |
keepAliveTime | 空闲线程存活时间 |
workQueue | 任务队列(ArrayBlockingQueue等) |
threadFactory | 线程创建工厂 |
handler | 拒绝策略(AbortPolicy等) |
ExecutorService pool = Executors.newFixedThreadPool(5);
pool.execute(() -> {
// 执行任务
});
pool.shutdown();
轻量级线程,由用户态调度: - Go语言的goroutine - Python的asyncio - Kotlin的coroutine
基于消息传递的并发模型: - Erlang/Elixir的核心并发机制 - Akka框架实现(Scala/Java)
适用于计算密集型任务: - OpenMP - CUDA - Java Stream API
线程作为现代编程的核心概念,其重要性体现在: 1. 充分利用多核CPU的计算能力 2. 提高程序响应速度(特别是GUI应用) 3. 优化资源利用率(I/O等待时执行其他任务)
掌握线程技术需要理解: - 线程生命周期管理 - 同步与通信机制 - 常见并发问题的解决方案 - 现代并发编程的最佳实践
随着硬件发展(多核/众核处理器),对线程技术的深入理解将成为开发者必备的核心技能之一。
字数统计:约2950字
最后更新:2023年10月
参考资料:《操作系统概念》、《Java并发编程实战》、POSIX Threads文档
“`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。