penglongli / blog

18 stars 1 forks source link

进程、线程、协程 #65

Open penglongli opened 6 years ago

penglongli commented 6 years ago

进程和线程都是独立的执行空间。当运行一个应用程序的时候,操作系统会为这个应用程序启动一个进程,我们可以把进程看做所要运行的程序在运行中需要用到和维护的各种资源的容器。

线程是操作系统能够进行运算调度的最小单位,是进程中的基本运行单元。一个进程可以包含多个线程,同进程中的多个线程共享内存空间。

协程(coroutine)类似于线程的概念,但并不是线程。线程属于操作系统层面,coroutine 属于程序层面。下边以 goroutine 做介绍。

Go 的运行时能够把大量独立执行的 functions-coroutines 多路复用到较少数量的线程上(可以认为:同进程下 goroutine 的数量 <= 线程数量)。每个 goroutine 有大概几千字节的堆栈,可根据需要增长,因此在程序中创建几十万个 goroutines 是没有任何问题的。

参考:

下文参考《Go in Action》简单介绍下 goroutine 的调度机制

goroutine 调度

上图的标识:

在 Go 的 1.5 版本及以后,其为每个物理处理器分配一个逻辑处理器(processor)。在上图,当 G0 发生了 I/O 阻塞,M0-G0 会从 P0 上分离出去(对于处理器来说,一个处理器同一个时刻只能做一件事情)。同时,调度器会从全局队列中选择另外一个 goroutine 来运行。

根据上图,在 G1 运行完成之后,M1 将会拿到 G2 开始工作。通常来说,当前在处理器中运行的线程在处理完绑定在其自身的 goroutine 后,会从工作队列中拿到另外的 goroutine 绑定到其上开始工作。如果找不到另外的 goroutine,其将会挂起。(https://groups.google.com/forum/#!topic/golang-nuts/A0aC12pDXNo )

关于 goroutine 运行的源码阅读放到以后(src/runtime/proc.go:findrunnable

Go 的并发同步模型

Go 的并发同步模型叫做通信顺序进程(Communicating sequuential processes, CSP)。CSP 是消息传递模型,通过在 goroutine 之间同步和传递消息来实现同步访问,而不是对数据加锁进行访问(虽然其支持加锁的方式)。

goroutine 使用 channel(分为有缓冲和无缓冲)来同步和传递数据。

参考: