X程

进程 线程 协程

IO密集型一般使用多线程或者多进程 CPU密集型一般使用多进程 强调非阻塞异步并发的一般都是使用协程

进程线程协程
分配和管理资源的基本单位进程的一个执行单元 CPU调度单位用户级线程
竞争计算机系统资源的基本单位轻量级进程轻量级线程

linux 用task_struct表示任务(process/thread) 每个thread对应一个task_struct对象

进程

一个进程就是一个正在执行程序的实例,包括程序计数器、寄存器和变量的当前值。

-----------
|Kernel(映射到虚拟内存)|最大地址
|argv environ|
|栈(stack)|
|(栈向下生长)|
|(堆向上生长)|
|堆(heap)|
|BSS(未初始化的全局变量)|
|数据段(.data)|
|文本段(.text)|0
--------------
1
2
3
4
5
6
7
8
9
10
11

内存中的进程

进程创建时分配的资源

  • pid
  • CPU时间
  • 内存(虚拟内存)
  • 文件
  • IO设备...
PCB

进程控制块:操作系统内的进程表示

  • 进程状态
  • 程序计数器(PC)
  • CPU寄存器
  • CPU调度信息
    • 基地址
    • 页表
  • 内存管理信息
  • 记账信息(accounting info) CPU时间等信息
  • IO信息

task_struct in <linux/sched.h>

上下文切换:

  • PCB
  • 内存交换(in/out)
    • 动态内存请求(request_memory/release_memory)
页表

实现

  • 一组专用寄存器 -- 小页表可用
  • 内存+页表基地址寄存器(Page-Table Base Register, PTBR) -- 太慢
  • 内存+PTBR+TLB(保存少量页表条目)

线程

线程有自己的寄存器和堆栈

多线程模型(用户线程与内核线程的关系)

  • 多对一
  • 一对一
  • 多对多
    • 变种:Hybrid 多对多+一对一
TLS(Thread Local Storage)

线程本地存储 在线程中可见(类似于线程的static)

局部变量仅在作用域可见

#include<iostream>
#include<thread>
thread_local int count = 0;
void incr(const char*tag){
  ++count;
  std::cout<<"tag: "<<tag<<" count: "<<count<<std::endl;
}
int main(){
  std::thread([](const char*s){
    incr(s);
    incr(s);
    incr(s);
  },"thread-1").join();
  std::thread([](const char*s){
    incr(s);
    incr(s);
    incr(s);
  },"thread-2").join();
  return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

运行结果

tag: thread-1 count: 1
tag: thread-1 count: 2
tag: thread-1 count: 3
tag: thread-2 count: 1
tag: thread-2 count: 2
tag: thread-2 count: 3
1
2
3
4
5
6

进程与线程

进程线程
资源/地址空间独立地址空间(系统分配资源:内存 IO)共享当前进程地址空间和资源
健壮性进程间不会相互影响线程崩溃会导致进程崩溃
上下文切换存储PCB 寄存器存储 换页(TLB)存储TCB 寄存器存储

状态一样: 就绪 阻塞 运行(+ 创建 结束)

上下文切换

进程线程协程
存储PCB 寄存器存储 换页(TLB)存储TCB 寄存器存储 堆栈(比协程大)寄存器(栈 无栈/有栈协程) 用户级线程(没id 没有task_struct内核对象)

参考