多线程
并发和并行
- 并发(concurrency)
- 两个或多个事件在同一时间间隔发生

- 两个或多个事件在同一时间间隔发生
- 并行(parallellism)
- 两个或者多个事件在同一时刻发生

- 两个或者多个事件在同一时刻发生
协程
- 进程:
- 分配系统资源(CPU 时间、内存等)基本单位
- 有独立的内存空间,切换开销大
- 线程:进程的一个执行流,是 CPU 调度并能独立运行的的基本单位
- 同一进程中的多线程共享内存空间,线程切换代价小
- 多线程通信方便
- 从内核层面来看线程其实也是一种特殊的进程,它跟父进程共享了打开的文件和文件系统信息,共享了地址空间和信号处理函数
- 协程
- Go 语言中的轻量级线程实现
- Golang 在 runtime、系统调用等多方面对 goroutine 调度进行了封装和处理,当遇到长时间执行或者进行系统调用时,会主动把当前 goroutine 的 CPU (P) 转让出去,让其他 goroutine 能被调度并执行,也就是 Golang 从语言层面支持了协程。
Communicating Sequential Process
- CSP
- 描述两个独立的并发实体通过共享的通讯 channel 进行通信的并发模型。
- Go 协程 goroutine
- 是一种轻量线程,它不是操作系统的线程,而是将一个操作系统线程分段使用,通过调度器实现协作式调度。
- 是一种绿色线程,微线程,它与 Coroutine 协程也有区别,能够在发现堵塞后启动新的微线程。
- 通道 channel
- 类似 Unix 的 Pipe,用于协程之间通讯和同步。协程之间虽然解耦,但是它们和 Channel 有着耦合。
线程和协程的差异
- 每个 goroutine (协程) 默认占用内存远比 Java 、C 的线程少
- goroutine:2KB
- 线程:8MB
- 线程 goroutine 切换开销方面,goroutine 远比线程小
- 线程:涉及模式切换(从用户态切换到内核态)、16个寄存器、PC、SP...等寄存器的刷新
- goroutine:只有三个寄存器的值修改 - PC / SP / DX.
- GOMAXPROCS
- 控制并行线程数量
协程示例
启动新协程:
go functionName() {
for i := 0; i < 10; i++ {
go fmt.Println(i)
}
time.Sleep(time.Second)
}