线程: 执行指令序列
保留了并发的优点, 避免了进程切换的代价. 实质: 映射表不变, PC指针变.
价值, 用处
浏览器
- 一个线程用来从服务器接收数据
- 一个线程用来显示文本
- 一个线程用来处理图片(解压缩)
- 一个线程用来显示图片
接收数据线程等待时可以切换到另一个线程(如显示文本), 更加高效利用CPU, 程序交互更加人性化.
线程切换
多线程执行互不干扰, 所以一个线程执行序列对应一个(或套)栈. 线程切换就是切换TCB.
TCB (Thread Control Block)
保存线程的信息(执行序列的栈). 与PCB相似, 只是比PCB储存的信息少而已.
用户级线程
用户态切来切去. CPL为3. TCB在用户程序中.
void ThreadCeate(A)
{
TCB *tcb = malloc(); // 申请内存创建TCB
*stack = malloc(); // 创建栈
*stack = A; // 保存栈
tcb.esp = stack
}
// 线程切换
void Yield()
{
TCB2.esp = esp;
esp = TCB1.esp; // esp: CPU寄存器
// jmp xxx; // 不需要再jmp xxx, 因为调用Yield时已经把Yield后面执行的内容压栈.
}
缺点
一个进程里的某个用户级线程触发系统IO(如网卡, 磁盘等)后系统会切换到其他进程执行. 这个进程其他线程就无法执行.
核心级线程
多"套"(用户栈 + 内核栈)TCB在内核中. 中断进入内核
优点
多核心CPU支持, 核心级线程可以并行执行.