gorouting
ddatsh
CSP是 用于描述两个独立的并发实体,通过共享的通讯 channel进行通信的并发模型
CSP中channel是第一类对象,它不关注发送消息的实体,而关注与发送消息时使用的channel
这是一套独立于语言的东西
思考
CPU:核心、超线程
OS:线程
编程语言:线程池
基本任何计算都要经由CPU,而CPU的核数直接决定了能给CPU执行几件事情
常用的OS内部都有一个轮询,用时间片形式分配任何轮流使用CPU执行计算,线程就是这些任务的载体
线程是操作系统级别用来共享CPU的一种技术实现
,多线程编程早在各大语言遍地开花,被用的惟妙惟肖,百花齐放
线程的开销
- 内存
- 调度器压力(线程上下文切换等)
线程可持有逻辑数据(比如,HttpContext.Current等对象),必定占用内存
如果CPU是4核的,同时只能处理4件任务,OS的线程越多他们轮训一整圈所耗的时间就更长
而每次调度线程时都需要复制当前线程上下文的状态,再去读取准备调度线程上下文的状态
多线程所执行的东西尽可能避免共享,不然效率还是可能不如单线程
许多语言runtime中,线程与操作系统的线程是一一对应的
协程
线程是为了共享CPU,而协程是为了共享线程
协程是应用层面的自有“线程”实现。在不改变OS的线程逻辑下,自己构建了一套 “线程”系统
为什么不直接改动OS的线程,让其更轻?
1是历史兼容性问题
2是必要性问题,线程是一个很好的抽象逻辑。实现协程完全可以通过线程来完成
场景
爬虫 百度、google、bing
- 多线程做法
启动三个线程,分别发起GET请求。用三个线程
- 协程做法
启动一个线程
对每个发起GET请求,将任务放入队列
可以只需要一个执行线程(大多数实现来说至少需要两个线程,需要一个后台线程监听任务队列,当任务完成后再分配一个可用线程去处理下面的逻辑)
协程也可以与线程一一对应,比如 8核 CPU,同时跑4个协程也可以分配4线程单独去处理这4个任务,取决于调度算法
总结
协程为了提升线程利用率,减少线程的无用功(大多数是IO堵塞),协程也更适合IO密集型的场景