typora/note/Go/通信并发.md
2024-12-12 10:48:55 +08:00

2.6 KiB
Raw Permalink Blame History

并发&&并行

  • 并发不是并行
  • 并发是应用结构设计相关的概念,而并行只是程序执行期的概念
  • 并行的必要条件是具有多个处理器或多核处理器,否则无论是否是并发的设计,程序执行时都有且仅有一个任务可以被调度到处理器上执行

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 包中的互斥锁、条件变量、读写锁、原子操作等)