typora/note/Go/通信并发.md

34 lines
2.6 KiB
Markdown
Raw Normal View History

2024-12-11 21:48:55 -05:00
### 并发&&并行
- 并发不是并行
- 并发是应用结构设计相关的概念,而并行只是程序执行期的概念
- 并行的必要条件是具有多个处理器或多核处理器,否则无论是否是并发的设计,程序执行时都有且仅有一个任务可以被调度到处理器上执行
### Go并发方案
- Go 的并发方案goroutine
- Go 并没有使用操作系统线程作为承载分解后的代码片段(模块)的基本执行单元
- 实现了goroutine这一由 Go 运行时runtime负责调度的、轻量的用户级线程为并发程序设计提供原生支持
- 无论是 Go 自身运行时代码还是用户层 Go 代码,都无一例外地运行在 goroutine 中
### goroutine优势
- 资源占用小,每个 goroutine 的初始栈大小仅为 2k
- 由 Go 运行时而不是操作系统调度goroutine 上下文切换在用户层完成,开销更小
- 在语言层面而不是通过标准库提供。goroutine 由go关键字创建一退出就会被回收或销毁开发体验更佳
- 语言内置 channel 作为 goroutine 间通信原语,为并发设计提供了强大支撑
### goroutine使用
#### 创建goroutine
- Go 语言通过go关键字+函数/方法的方式创建一个 goroutine
- Go 也可以基于匿名函数 / 闭包创建 goroutine
- 创建 goroutine 后go 关键字不会返回 goroutine id 之类的唯一标识 goroutine 的 id
- 一个应用内部启动的所有 goroutine 共享进程空间的资源,如果多个 goroutine 访问同一块内存数据,将会存在竞争,需要进行 goroutine 间的同步
- 创建后,新 goroutine 将拥有独立的代码执行流,并与创建它的 goroutine 一起被 Go 运行时调度
#### 退出goroutine
- goroutine 的执行函数的返回,就意味着 goroutine 退出goroutine 执行的函数或方法即便有返回值Go 也会忽略这些返回值,如果需要返回值,通过 goroutine 间的通信来实现
- main goroutine 退出那么也意味着整个应用程序的退出其他的goroutine也就都退出
#### goroutine间的通信
> 操作系统线程间的通信方式共享内存、信号signal、管道pipe、消息队列、套接字socket基于对内存的共享的
- channel 符合`CSPCommunicationing Sequential Processes通信顺序进程`模型的通信方式,通过使用 channel 将goroutine组合在一起
- Go 也支持传统的、基于共享内存的并发模型,并提供了基本的低级别同步原语(主要是 sync 包中的互斥锁、条件变量、读写锁、原子操作等)