Skip to content

多线程

并发和并行

  • 并发(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
    • 控制并行线程数量

协程示例

code

启动新协程:

go functionName() {
    for i := 0; i < 10; i++ {
        go fmt.Println(i) 
    }
    time.Sleep(time.Second)
}