Go语言的并发指的是能让某个函数独立于其他函数运行的能力。当一个函数创建为goroutine时,Go会将其视为一个独立的工作单元。这个单元会被调度到可用的逻辑处理器上执行。
操作系统会在物理处理器上调度线程来运行,而Go语言的运行时会在逻辑处理器上调度goroutine来运行。每个逻辑处理器都分别绑定到单个操作系统线程。
在1.5版本上,Go语言的运行时默认会为每个可用的物理处理器分配一个逻辑处理器。在1.5之前的版本中,默认给整个应用程序只分配一个逻辑处理器。
有时,正在运行的goroutine需要执行一个阻塞的系统调用,如打开一个文件。当这类调用发生时,线程和goroutine会从逻辑处理器上分离,该线程会继续阻塞,等待系统调用的返回。
与此同时,这个逻辑处理器就失去了用来运行的线程。所以调度器会创建一个新线程,将其绑定到该逻辑处理器上。之后,调度器会从本地运行队列里选择另一个goroutine来运行。
一旦被阻塞的系统调用执行完毕并返回,对应的goroutine会放回到本地运行队列,而之前线程会保存好,以便之后继续使用
如果一个goroutine需要做一个网络I/O调用,流程上会有些不一样。
在这种情况下,goroutine会和逻辑处理器分离,并移到集成了网络轮询器的运行时。一旦该轮询器指示某个网络读或者写操作已经就绪,对应的goroutine就会重新分配到逻辑处理器上来完成操作。
并发(concurrency)不是并行(parallelism)。并行是让不同的代码