Go Concurency Programming
是Go
并发编程系列的梳理, 由基础到进阶包括: 基础概念(并发, 并行, 进程, 线程, 协程
), Go
内置数据结构(Channel
), Go
内置使用语句Select, Sync, Mutex
, 推荐编码范式(PipeLine, Fan-in, Fan-Out ...
), Go
高级使用原语(Context
), Go
底层实现原理: GPM, CSP
, 经典案例;
本文过一遍并发编程中的基础概念: 并发, 并行, 进程, 线程, 协程, GoRoutine
;
进程, 线程与协程
Process thread coroutine
- 进程
Process
:是程序在操作系统上的一次运行过程, 是系统进行资源(CPU, Memory ...
)分配与调度的独立单位; 例如打开浏览器, 就是启动了一个浏览器进程, 关闭浏览器, 就是结束了一个浏览器进程, 在这期间一般称为运行时(Runtime
), 系统会对浏览器进程分配其所需要的CPU, Memory
等资源. 如果分配失败一般会引起Crash
, 例如OOM
错误, 用户常见的内存空间不足
等错误; - 线程
thread
: 是进程的执行实体, 它是CPU
调度与分配的独立单位, 由进程生成. 一个进程可以创建/撤销多个线程, 多个线程间可以并发执行. 例如QQ
进程, 会生成一个thread
用于监控QQ Message
, 生成一个thread
用于监听QQ Mail
等; - 协程
coroutine
: 是用户级别的线程
, 其调度由用户控制, 属于轻量级的线程, 一个线程可以创建多个协程, 在Go中就是大名鼎鼎的GoRoutine
概念;
并发与并行
Concurrency and parallelism
- 并发
Concurrency
: 指的是多线程程序在单核CPU上运行, 依赖快速时间片轮转的方式, 使得达到了伪并行的效果; - 并行
parallelism
: 指的是多线程程序在多核CPU上运行;
并发与并行总是被一起提出来, 是由于其对于用户端的感受是无差别的,即程序在同时处理多个动作, 例如在浏览器上同时开启多个网页.
goroutine
goroutine
是Go
中的coroutine
实现, 是Go Concurrency Programming
实现的基础特性. 通过goroutine
可以轻松的将函数/方法通过并发的方式运行, 相比较于传统的创建线程的方式, 其可读性更强, 性能开销更小, 简单示例:
1 | package main |
在上面的例子中, sayHello
函数作为一个goroutine
并发执行. 通过关键字**go
**就可以轻松发起一个goroutine
;
goroutine
是非常轻量的, 每个goroutine
初期仅占用几KB
, 可以轻松开启十万级别的goroutines
,而不会对性能产生太大影响。Go
运行时将它们多路复用到少数操作系统线程上,runtime
处理goroutines
的调度和执行。
goroutines
的美妙之处在于其简单易用。与传统的线程模型相比,它们使您能够以更直接和可读的方式编写并发代码。然而,请记住,在必要时,可能需要适当的同步机制(如通道或同步原语)来协调goroutine
之间的通信。