线程: 执行指令序列

保留了并发的优点, 避免了进程切换的代价. 实质: 映射表不变, 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支持, 核心级线程可以并行执行.