gorouting

ddatsh

dev #go

CSP是 用于描述两个独立的并发实体,通过共享的通讯 channel进行通信的并发模型

CSP中channel是第一类对象,它不关注发送消息的实体,而关注与发送消息时使用的channel

这是一套独立于语言的东西

思考

CPU:核心、超线程

OS:线程

编程语言:线程池

基本任何计算都要经由CPU,而CPU的核数直接决定了能给CPU执行几件事情

常用的OS内部都有一个轮询,用时间片形式分配任何轮流使用CPU执行计算,线程就是这些任务的载体

线程是操作系统级别用来共享CPU的一种技术实现,多线程编程早在各大语言遍地开花,被用的惟妙惟肖,百花齐放

线程的开销

  1. 内存
  2. 调度器压力(线程上下文切换等)

线程可持有逻辑数据(比如,HttpContext.Current等对象),必定占用内存

如果CPU是4核的,同时只能处理4件任务,OS的线程越多他们轮训一整圈所耗的时间就更长

而每次调度线程时都需要复制当前线程上下文的状态,再去读取准备调度线程上下文的状态

多线程所执行的东西尽可能避免共享,不然效率还是可能不如单线程

许多语言runtime中,线程与操作系统的线程是一一对应的

协程

线程是为了共享CPU,而协程是为了共享线程

协程是应用层面的自有“线程”实现。在不改变OS的线程逻辑下,自己构建了一套 “线程”系统

为什么不直接改动OS的线程,让其更轻?

1是历史兼容性问题

2是必要性问题,线程是一个很好的抽象逻辑。实现协程完全可以通过线程来完成

场景

爬虫 百度、google、bing

启动三个线程,分别发起GET请求。用三个线程

启动一个线程

对每个发起GET请求,将任务放入队列

可以只需要一个执行线程(大多数实现来说至少需要两个线程,需要一个后台线程监听任务队列,当任务完成后再分配一个可用线程去处理下面的逻辑)

协程也可以与线程一一对应,比如 8核 CPU,同时跑4个协程也可以分配4线程单独去处理这4个任务,取决于调度算法

总结

协程为了提升线程利用率,减少线程的无用功(大多数是IO堵塞),协程也更适合IO密集型的场景